Modular form builder & renderer for React.
eSheet is a TypeScript-first Nx monorepo providing composable packages for embedding a visual form builder and renderer into any React application — no lock-in, no required backend.
- Live Demo — builder + renderer playground
- Documentation — full API & usage docs
| Package | Description |
|---|---|
@esheet/core |
Zod schemas, Zustand stores, conditional logic engine — no React |
@esheet/fields |
19 built-in field components (text, choice, scale, matrix, rich, layout) |
@esheet/builder |
Drag-and-drop visual form builder (<EsheetBuilder />) |
@esheet/renderer |
Read-only React form renderer (<EsheetRenderer />) |
@esheet/renderer-standalone |
Standalone mount API and global registration |
@esheet/renderer-blaze |
Meteor Blaze template integration |
All packages are versioned together and published to npm under the @esheet scope.
# Builder (includes fields + core as peer deps)
npm install @esheet/builder
# Renderer only
npm install @esheet/renderer
# Optional integrations
npm install @esheet/renderer-standalone
npm install @esheet/renderer-blazeimport { EsheetBuilder } from '@esheet/builder';
import '@esheet/builder/dist/index.css';
function App() {
const [definition, setDefinition] = useState(emptyForm);
return <EsheetBuilder definition={definition} onChange={setDefinition} />;
}import { EsheetRenderer, EsheetRendererHandle } from '@esheet/renderer';
function App() {
const rendererRef = useRef<EsheetRendererHandle>(null);
return (
<>
<EsheetRenderer formData={definition} ref={rendererRef} />
<button onClick={() => console.log(rendererRef.current?.getResponse())}>
Submit
</button>
</>
);
}mSheet/
├── packages/
│ ├── core/ # @esheet/core — types, stores, logic (no React)
│ ├── fields/ # @esheet/fields — 19 field components
│ ├── builder/ # @esheet/builder — visual builder UI
│ ├── renderer/ # @esheet/renderer — form renderer
│ ├── renderer-standalone/ # @esheet/renderer-standalone — standalone integration
│ └── renderer-blaze/ # @esheet/renderer-blaze — blaze integration
└── apps/
├── demo/ # Vite playground (builder + renderer routes)
└── docs/ # Docusaurus documentation site
@esheet/core
↑
@esheet/fields
↑ ↑
@esheet/builder @esheet/renderer
↑ ↑
@esheet/renderer-standalone @esheet/renderer-blaze
This workspace uses Nx. All tasks run through Nx — do not invoke tsc, vite, or vitest directly.
- Node.js ≥ 20
- npm workspaces (builtin)
npm install# Build all packages
npx nx run-many -t build
# Run tests across all packages
npx nx run-many -t test
# Lint all projects
npx nx run-many -t lint
# Type-check all projects
npx nx run-many -t typecheck
# Serve the demo app locally
npx nx serve demo
# Run only tasks affected by your changes
npx nx affected -t lint,test,buildnpx nx build @esheet/core
npx nx build @esheet/buildernpx nx serve demo
# → http://localhost:4200npx nx serve docs
# → http://localhost:3000chmod +x deploy/scripts/setup-nginx.sh
./deploy/scripts/setup-nginx.sh
chmod +x deploy/scripts/deploy-static.sh
./deploy/scripts/deploy-static.sh- Nginx config in repo:
deploy/nginx/default.conf - Deploy script in repo:
deploy/scripts/deploy-static.sh - Setup helper in repo:
deploy/scripts/setup-nginx.sh - Runbook in repo:
deploy/RUNBOOK-nginx-atomic.md
Packages are versioned together using nx release with conventional commits.
| Commit prefix | Version bump |
|---|---|
fix: |
patch |
feat: |
minor |
feat!: or BREAKING CHANGE: |
major |
# Preview what would change (no files written)
npx nx release --dry-run
# First-ever release (before any git tag exists)
npx nx release --first-release
# Subsequent releases (bump auto-determined from commits since last tag)
npx nx releaseA GitHub Release and CHANGELOG.md are generated automatically. Set GITHUB_TOKEN in your environment before running nx release to enable GitHub Release creation.
- Fork and clone the repo
npm install- Create a branch:
git checkout -b feat/my-feature - Make changes — run
npx nx affected -t lint,test,buildbefore committing - Use conventional commits in your commit messages
- Open a pull request
MIT © MIE