Thank you for your interest in contributing to SuperDoc! Whether you're fixing a bug, improving documentation, or adding a feature, we appreciate your help.
- Ways to Contribute
- Architecture Overview
- Contribution Areas
- Your First PR
- Development Setup
- Pull Request Process
- Release Process
- Style Guidelines
- Community
Contributing isn't just about writing code. Here are several ways you can help:
Report bugs with reproduction files Open a .docx in SuperDoc and compare it with Microsoft Word. If something looks different, open an issue with the file attached. Good bug reports with reproduction files are incredibly valuable.
Improve documentation
Our docs live in apps/docs/ (docs.superdoc.dev) and are built with Mintlify. Fix typos, add code examples, improve explanations, or write guides. Run pnpm run dev:docs to preview locally. Documentation PRs are always welcome and a great way to get started.
Add examples and integrations
Create example projects showing SuperDoc with different frameworks (Next.js, Nuxt, Remix, etc.) in the examples/ directory.
Add test coverage Write unit tests or visual regression tests for existing features. Better test coverage helps everyone.
Fix bugs and implement features Check our good first issues for approachable tasks, or help wanted for meatier items.
Help the community Answer questions on Discord.
SuperDoc is a document editing and rendering library for the web. Understanding its architecture will help you find the right place to make changes.
SuperDoc uses its own rendering pipeline -- ProseMirror is NOT used for visual output:
DOCX File
β super-converter (parse OOXML into ProseMirror document)
β pm-adapter (convert PM nodes into FlowBlocks)
β layout-engine (paginate FlowBlocks into Layouts)
β DomPainter (render Layouts to DOM)
A hidden ProseMirror Editor instance manages document state and editing commands, but its DOM is never shown to the user. All visual rendering goes through DomPainter.
packages/
superdoc/ Main entry point (npm: superdoc)
react/ React wrapper (@superdoc-dev/react)
super-editor/ ProseMirror editor core
src/editors/v1/
core/
super-converter/ DOCX import/export (OOXML β ProseMirror)
extensions/ Editing behaviors (bold, lists, tables, etc.)
layout-engine/ Layout & pagination pipeline
pm-adapter/ ProseMirror β Layout bridge
layout-engine/ Pagination algorithms
painters/dom/ DOM rendering (DomPainter)
style-engine/ OOXML style resolution & cascade
contracts/ Shared type definitions
ai/ AI integration
collaboration-yjs/ Collaboration server
shared/ Internal utilities
examples/ Framework integration examples
tests/visual/ Visual regression tests (Playwright)
| What you want to change | Where to look |
|---|---|
| How something looks (visual rendering) | layout-engine/painters/dom/ |
| Style resolution (fonts, colors, borders) | layout-engine/style-engine/ |
| Data flowing from editor to renderer | layout-engine/pm-adapter/ |
| Editing behavior (keyboard, commands) | super-editor/src/editors/v1/extensions/ |
| DOCX import/export | super-editor/src/editors/v1/core/super-converter/ |
| React integration | packages/react/ |
| Main entry point (Vue) | packages/superdoc/ |
| Visual regression tests | tests/visual/ |
The importer stores raw OOXML properties. The style-engine resolves them at render time.
The converter (super-converter/) parses and stores only what is explicitly in the XML. The style-engine (layout-engine/style-engine/) handles all cascade logic (defaults -> table style -> conditional formatting -> inline overrides). Don't resolve styles during import -- it bakes them into node attributes and loses the original document intent on export.
These are areas where community contributions are especially welcome. Check issues labeled good first issue for specific tasks.
| Area | Difficulty | Where to Look | What to Do |
|---|---|---|---|
| Documentation | Easy | docs.superdoc.dev | Fix gaps, add code examples, improve explanations |
| Examples | Easy | examples/ |
Create framework integration examples |
| Test coverage | Easy-Medium | tests/visual/ |
Add tests for existing features |
| Rendering parity | Medium | layout-engine/painters/dom/ |
Open a .docx in Word and SuperDoc, fix visual differences |
| Browser compatibility | Medium | super-editor/, layout-engine/ |
Fix Firefox/Safari-specific bugs |
| Copy/paste | Medium | super-editor/src/editors/v1/extensions/ |
Fix formatting loss when pasting from Word, Google Docs, browsers |
| DOCX import coverage | Medium-Hard | super-editor/src/editors/v1/core/super-converter/ |
Support additional OOXML tags and elements |
Here's a step-by-step walkthrough to make your first contribution:
- Browse good first issues
- Or pick from the contribution areas above
- Comment on the issue to let others know you're working on it
# Fork the repo on GitHub, then:
git clone https://github.com/<your-username>/superdoc.git
cd superdoc
# Install dependencies (pnpm 9+ required)
pnpm install
# Start the dev server
pnpm devThe dev server gives you a live editor to test changes.
git checkout -b fix/your-change-description
# or: feat/your-change-description
# or: docs/your-change-descriptionUse the architecture overview and the "Where to Make Changes" table to locate the right files. When in doubt, search for keywords:
# Find files by name
find packages/ -name "*.js" | xargs grep -l "your-keyword"
# Search file contents
grep -r "your-keyword" packages/ --include="*.js" -l- Follow existing code patterns in the file you're editing
- Keep changes focused -- one fix or feature per PR
- Add or update tests for your changes
# Run the full test suite
pnpm test
# Run tests for a specific package
pnpm run test:editor # super-editor tests
pnpm run test:superdoc # superdoc package tests
# Check formatting and linting
pnpm run format:check
pnpm run lintgit add <files>
git commit -m "fix: describe your change"
git push origin fix/your-change-descriptionFollow Conventional Commits for your commit message (see Commit Messages below).
Open a PR against the main branch. In the description:
- Describe what you changed and why
- Link to the related issue (e.g.,
Closes #123) - Include screenshots for visual changes
- Add a test plan if applicable
CI will run automatically. A maintainer will review your PR and provide feedback.
git clone https://github.com/<your-username>/superdoc.git
cd superdoc
pnpm install
pnpm devpnpm dev # Start dev server (from examples/)
pnpm build # Build all packages
pnpm test # Run all tests
pnpm run lint # Run ESLint
pnpm run format # Run Prettierfeature/descriptionfor new featuresfix/descriptionfor bug fixesdocs/descriptionfor documentation changesperf/descriptionfor performance improvements
Follow Conventional Commits:
feat: add real-time cursor sharing
- Implement cursor position tracking
- Add websocket connection for updates
Closes #123
Your commit type determines the version bump on release:
| Commit Type | Version Bump | Example |
|---|---|---|
fix: |
Patch (0.0.X) | fix: resolve cursor positioning bug |
feat: |
Minor (0.X.0) | feat: add PDF export functionality |
feat!: or BREAKING CHANGE: |
Major (X.0.0) | feat!: redesign document API |
chore:, docs:, refactor:, test: |
No version change | docs: update README |
When you open a PR, the following checks run automatically:
- Commit message validation
- Code formatting (Prettier)
- Linting (ESLint)
- Unit tests
- Visual regression tests (if UI changes)
- Changes are focused (one fix/feature per PR)
- Tests added or updated
- Test suite passes locally (
pnpm test) - Code is formatted (
pnpm run format:check) - Commit messages follow conventional commits
- PR description links to related issue
SuperDoc uses automated CI/CD with semantic-release. No manual version bumps are needed.
mainbranch -> Pre-release versions (@nexttag on npm)stablebranch -> Stable versions (@latesttag on npm)
Every merge to main publishes a pre-release automatically. Stable releases are promoted from main via a GitHub Actions workflow.
- Use JavaScript with JSDoc type annotations for all new code
- Follow the existing code style (enforced by ESLint and Prettier)
- Use ES6+ features
- Document public APIs using JSDoc
- Keep lines under 100 characters
# Check formatting
pnpm run format:check
# Auto-fix formatting
pnpm run format
# Run linting
pnpm run lint
# Fix linting issues
pnpm run lint:fixThis project and everyone participating in it are governed by our Code of Conduct. By participating, you are expected to uphold this code. Please report unacceptable behavior to support@superdoc.dev.
We value every contribution. Community contributors are featured in our README and recognized on Discord.
Questions? Join our Discord.