Thanks for wanting to help. This project has a few unusual constraints — please read them before opening a PR.
- Zero dependencies. No npm packages ship to the browser. No CDN links, no external fonts, no analytics.
- One file. The entire application lives in
src/index.js. Do not split it into modules or introduce a bundler. - No build step. What you write is what gets deployed.
- Vanilla JavaScript only. No frameworks, no TypeScript compilation.
These constraints are the point of the project, not an accident.
Test your change in all of the following:
- Light theme and dark theme
- English and Persian (RTL) interface
- Studio mode and Canvas mode
- Export as PNG and SVG, then open the exported SVG directly in a browser
- Desktop and a narrow mobile viewport
-
npm run checkpasses (syntax check)
The export pipeline is the most fragile part of the codebase. If you touch it, be aware:
- Any attribute value written into the SVG must go through
attrEscape(). Font stacks contain double quotes and will corrupt the document otherwise. - Any text content must go through
xmlEscape(). - The
svg:rootoverride rule must remain, otherwise the app's ownsvg { width: 16px }icon rule shrinks the exported file to 16 pixels when opened standalone. - Always await
document.fonts.readybefore serializing. - Verify the exported SVG parses: open it directly in Firefox and Chrome, not just as an
<img>.
Add an entry to the THEMES object. Include every token the existing themes define, and check contrast for comments and punctuation — they are the first things to become unreadable.
Add the English string as the key and the Persian string as the value in FA_MAP. Keep Persian strings short; the sidebar is narrow.
Use a short imperative summary, optionally prefixed:
fix: escape attribute values in SVG export
feat: add WebP export format
docs: clarify custom domain setup
Open an issue with: what you did, what you expected, what happened, your browser and OS, and — if it is an export bug — the exported file itself.