Thank you for your interest in contributing to Fict!
- Node.js 20+
- pnpm 9+
# Clone the repository
git clone https://github.com/fictjs/fict.git
cd fict
# Install dependencies
pnpm install
# Install git hooks
pnpm prepare
# Start development
pnpm devpackages/runtime- Core reactive runtimepackages/compiler- Babel compilerpackages/vite-plugin- Vite integrationpackages/eslint-plugin- ESLint rulespackages/devtools- Browser DevToolspackages/docs-site- Documentation websitepackages/testing-library- Testing librarypackages/ssr- Server-side renderingexamples/- Example applications
pnpm test # Run all tests
pnpm test:watch # Watch mode
pnpm test:coverage # With coverage- The TypeScript transformer emits fine-grained DOM bindings by default; set
fineGrainedDom: falsein yourtsconfigplugin entry only when bisecting regressions. - The runtime uses fine-grained updates exclusively. All components benefit from surgical DOM updates and node reuse.
pnpm lint # ESLint
pnpm typecheck # TypeScript
pnpm format # Prettierpnpm build # Build all packages
pnpm build --filter @fictjs/runtime # Build specific packageWorkspace commands run Turbo through scripts/run-turbo.mjs. The wrapper selects
the local native compiler and includes its binary digest in the cache key; Turbo
also hashes the Rust sources, build manifests, diagnostic registry, and compiler
capabilities. Replacing an addon at the same path invalidates dependent builds.
To select a custom addon, set FICT_COMPILER_NATIVE_PATH. Relative paths resolve
from the workspace root. Commands that first build the native compiler also
replace the addon at that path; use node scripts/run-turbo.mjs run build to test
an already prepared binary. The selected path is passed to compiler hosts, while
the binary digest identifies it for caching. If the default
addon has not been built, non-native commands can run with caching disabled. An
explicit missing addon path is an error. Use the workspace commands so this
selection step also runs for tests, typechecking, and development builds.
After building, pnpm size measures the distributed ESM/CJS modules with production
constants and Brotli compression. It disables workspace TypeScript path aliases
and checks esbuild's actual module inputs so a published-package budget cannot
silently measure src files. Separate imports track synchronous and asynchronous
memo costs. pnpm test:size-boundaries exercises this boundary against conflicting
source aliases without requiring a repository build.
pnpm commitExamples:
feat(runtime): add batch update supportfix(compiler): handle edge case in JSX transformdocs: update API reference
When making changes that should be released:
pnpm changesetFollow the prompts to:
- Select changed packages
- Choose version bump type
- Write a summary
- Fork the repository
- Create a feature branch (
git checkout -b feat/amazing-feature) - Make your changes
- Add tests for new functionality
- Ensure all tests pass (
pnpm test) - Add a changeset if needed (
pnpm changeset) - Commit your changes
- Push to your fork
- Open a Pull Request
Please be respectful and constructive in all interactions.
Open an issue or start a discussion on GitHub.