Troubleshooting Guide
February 4, 2026 · View on GitHub
This guide helps you resolve common issues when using xcfreader.
Table of Contents
- Installation Issues
- Parsing Errors
- Browser Issues
- Node.js Issues
- Performance Issues
- TypeScript Issues
- FAQ
Installation Issues
pngjs not found
Error:
Cannot find module 'pngjs'
Solution:
If you're using Node.js and want PNG output, install pngjs:
npm install pngjs
For browser-only usage, pngjs is not needed. Use XCFDataImage instead of XCFPNGImage.
Module resolution errors
Error:
Cannot find module '@theprogrammingiantpanda/xcfreader/node'
Solution:
Ensure you're using Node.js 18+ and that your package.json has:
{
"type": "module"
}
Or use .mjs file extensions for ES modules.
Parsing Errors
XCFParseError: Invalid XCF file
Cause: The file is not a valid XCF file or is corrupted.
Solutions:
- Verify the file opens in GIMP
- Check the file isn't a different format (PNG, JPG, etc.) renamed to
.xcf - Try re-saving the file in GIMP
- Ensure the file isn't corrupted (check file size, re-download if from network)
UnsupportedFormatError
Cause: The XCF file uses features not yet supported by xcfreader.
Solutions:
- Check which GIMP version created the file
- Try saving the file in GIMP with older compatibility (File → Export As → XCF)
- Report the issue with the XCF file version info on GitHub Issues
File not found errors
Error:
ENOENT: no such file or directory
Solution: Use absolute paths or resolve paths relative to your working directory:
import path from 'path';
import { fileURLToPath } from 'url';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const xcfPath = path.resolve(__dirname, './images/file.xcf');
const parser = await XCFParser.parseFileAsync(xcfPath);
Browser Issues
Canvas errors
Error:
Failed to get 2D canvas context
Solutions:
- Ensure the canvas element exists in the DOM
- Check that you're calling
getContext('2d')correctly - Verify the browser supports Canvas API (all modern browsers do)
toDataURL() not working
Error:
toDataURL() requires a browser environment with Canvas support
Cause: You're calling toDataURL() in a Node.js environment.
Solution:
- In Node.js, use
XCFPNGImageandwriteImage()instead - In browsers, ensure you're using
XCFDataImagefrom the browser bundle
Large file memory issues
Symptom: Browser crashes or becomes unresponsive with large XCF files.
Solutions:
- Use Web Workers to parse files in a background thread
- Show a loading indicator while parsing
- Consider reducing image resolution in GIMP before export
- Split large images into multiple smaller XCF files
Node.js Issues
PNG output is blank/black
Causes:
- No visible layers in the XCF file
- All layers have 0% opacity
- Layers are outside the canvas bounds
Solutions:
- Check layer visibility in GIMP
- Verify layer opacity settings
- Use
parser.layersto inspect layer properties:parser.layers.forEach(layer => { console.log(`${layer.name}: visible=${layer.visible}, opacity=${layer.opacity}`); });
Image colors look wrong
Causes:
- Grayscale or indexed color mode
- High bit-depth precision (16-bit, 32-bit)
- Unusual blend modes
Solutions:
- Check the color mode:
parser.baseType - Check precision:
parser.precision - xcfreader automatically converts to 8-bit RGBA - this is expected behavior
Performance Issues
Slow parsing on large files
Solutions:
- Use streaming where possible (future enhancement)
- Parse files during build time instead of runtime
- Cache parsed results
- Consider using lower resolution source files
- Use the async API:
parseFileAsync()instead of blocking operations
High memory usage
Solutions:
- Dispose of parsed objects when done:
const parser = await XCFParser.parseFileAsync('./large.xcf'); const image = new XCFPNGImage(parser.width, parser.height); parser.createImage(image); await image.writeImage('./output.png'); // Let garbage collector reclaim memory parser = null; image = null; - Process files one at a time instead of loading all into memory
- Use smaller XCF files when possible
TypeScript Issues
Type errors with compositing modes
Error:
Type 'number' is not assignable to type 'CompositerMode'
Solution:
Use the CompositerMode enum instead of numbers:
import { CompositerMode } from '@theprogrammingiantpanda/xcfreader';
// Don't do this:
const mode = 3;
// Do this:
const mode = CompositerMode.NORMAL_MODE;
Missing type definitions
Error:
Could not find declaration file for module '@theprogrammingiantpanda/xcfreader'
Solution:
- Ensure you have the latest version installed
- Check that
node_modules/@theprogrammingiantpanda/xcfreader/dist/*.d.tsfiles exist - Restart your TypeScript language server / IDE
FAQ
Q: Which GIMP versions are supported?
A: xcfreader supports:
- GIMP 2.10.x (XCF v011 with 64-bit pointers) ✅
- GIMP 2.8.x (XCF v010 with 32-bit pointers) ✅
- GIMP 2.6.x and earlier ✅
Q: Can I use xcfreader in React/Vue/Angular?
A: Yes! Use the browser bundle:
import { XCFParser, XCFDataImage } from '@theprogrammingiantpanda/xcfreader/browser';
For React example:
function XCFViewer({ file }: { file: File }) {
const canvasRef = useRef<HTMLCanvasElement>(null);
useEffect(() => {
(async () => {
const arrayBuffer = await file.arrayBuffer();
const parser = XCFParser.parseBuffer(arrayBuffer);
const image = new XCFDataImage(parser.width, parser.height);
parser.createImage(image);
const canvas = canvasRef.current;
if (canvas) {
const ctx = canvas.getContext('2d');
canvas.width = parser.width;
canvas.height = parser.height;
ctx?.putImageData(image.imageData, 0, 0);
}
})();
}, [file]);
return <canvas ref={canvasRef} />;
}
Q: How do I render only specific layers?
A: Use the visible property when creating the image:
// Hide all layers first
parser.layers.forEach(layer => layer.visible = false);
// Show only specific layers
parser.getLayerByName('Background').visible = true;
parser.getLayerByName('Foreground').visible = true;
// Or use the web component:
<gpp-xcfimage src="image.xcf" visible="0,2,5"></gpp-xcfimage>
Q: Can I extract layer images individually?
A: Not directly, but you can:
- Hide all layers except the one you want
- Render the image
- Repeat for each layer
This is a planned feature for future releases.
Q: Does xcfreader support layer effects (drop shadow, glow, etc.)?
A: Layer effects are stored as parasites in XCF files. xcfreader parses parasites but doesn't render effects yet. This is planned for future releases.
Q: How do I handle errors gracefully?
A:
import { XCFParser, XCFParseError, UnsupportedFormatError } from '@theprogrammingiantpanda/xcfreader/node';
try {
const parser = await XCFParser.parseFileAsync('./image.xcf');
// ... use parser
} catch (error) {
if (error instanceof XCFParseError) {
console.error('Failed to parse XCF file:', error.message);
} else if (error instanceof UnsupportedFormatError) {
console.error('XCF format not supported:', error.message);
} else {
console.error('Unexpected error:', error);
}
}
Q: Can I convert XCF to other formats besides PNG?
A: In Node.js, xcfreader outputs PNG via pngjs. For other formats:
- Use
XCFPNGImageto get PNG - Use another library (like
sharp) to convert PNG to JPEG, WebP, etc.
In browsers:
- Use
XCFDataImage.toDataURL('image/jpeg')for JPEG - Use
XCFDataImage.toBlob('image/webp')for WebP
Q: Is there a size limit for XCF files?
A: No hard limit, but:
- Node.js: Limited by available memory (can handle multi-GB files)
- Browser: Limited by browser memory (typically handles files up to several hundred MB)
For very large files, consider processing server-side with Node.js.
Q: How do I report bugs or request features?
A:
- Check existing issues: https://github.com/andimclean/xcfreader/issues
- Create a new issue with:
- XCF file version (
parser.version) - GIMP version that created the file
- Minimal reproduction steps
- Error messages or unexpected behavior
- XCF file version (
Q: Can I contribute to xcfreader?
A: Yes! See CONTRIBUTING.md for guidelines.
Still Having Issues?
If your issue isn't covered here:
- Check the examples directory for working code
- Review the API documentation
- Search existing issues
- Create a new issue with detailed information about your problem