Modular form builder & renderer for React.
eSheet is a TypeScript-first pnpm workspace 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 />) with auto-detection of SurveyJS/MCP |
@esheet/adapters |
SurveyJS ↔ eSheet converters, MCP import/export, AI system prompt |
@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 formDataInput={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 (auto-detects SurveyJS/MCP)
│ ├── adapters/ # @esheet/adapters — SurveyJS/MCP converters, AI prompt
│ ├── 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/adapters
↑ ↑ ↑
@esheet/builder @esheet/renderer
↑ ↑
@esheet/renderer-standalone @esheet/renderer-blaze
This repository uses pnpm workspaces with explicit package scripts.
- Node.js ≥ 20
- Corepack
corepack enable
pnpm install# Build all packages
pnpm build
# Run tests across all packages
pnpm test
# Lint all projects
pnpm lint
# Type-check all projects
pnpm typecheck
# Serve the demo app locally
pnpm dev:demo
# Check formatting
pnpm format:check# Build a single package
pnpm --filter @esheet/core build
pnpm --filter @esheet/builder buildBefore committing, test your changes locally using gh act. This validates formatting, linting, tests, builds, typechecks, and release dry-runs.
Quick commands:
# Test CI workflow (format, lint, test, build, typecheck)
gh act pull_request -W .github/workflows/ci.yml --pull=false
# Test release workflow (dry-run release — does not publish)
gh act workflow_dispatch -W .github/workflows/release.yml -e release/act-dry-run-event.json --pull=false
# Test PR title validation
printf '{"pull_request":{"title":"fix(core): my change","number":1}}\n' > /tmp/pr-event.json
gh act pull_request -e /tmp/pr-event.json -W .github/workflows/pr-title-check.yml --pull=falseFor full setup instructions and troubleshooting, see .github/workflows/TESTING-LOCALLY.md.
pnpm dev:demo
# → http://localhost:5173pnpm dev:docs
# → http://localhost:3000pnpm --parallel --filter @esheet/demo --filter esheet-docs dev
# Demo → http://localhost:5173
# Docs → http://localhost:3000This runs both local dev servers at the same time in one terminal. Use Ctrl+C to stop both.
Cloudflare Pages publishes the combined documentation and demo layout:
- Documentation at
/ - Demo at
/demo/
Use pnpm build:cf as the build command and dist as the output directory. See the Cloudflare Pages runbook for the complete project settings, environment variables, routing behavior, and verification steps.
Packages are versioned together by the custom release script using conventional commits.
| Commit prefix | Version bump |
|---|---|
fix: |
patch |
feat: |
minor |
feat!: or BREAKING CHANGE: |
major |
# Preview what would change (no files written)
node release/release.mjs --dry-run
# First-ever release (before any git tag exists)
node release/release.mjs --dry-run --bump=patch
# Subsequent releases (bump auto-determined from commits since last tag)
node release/release.mjs --bump=patchA GitHub Release and CHANGELOG.md are generated automatically. Set GITHUB_TOKEN in your environment before running a full release.
- Fork and clone the repo
corepack enable && pnpm install- Create a branch:
git checkout -b feat/my-feature - Make changes — run
pnpm lint && pnpm test && pnpm typecheck && pnpm buildbefore committing - Use conventional commits in your commit messages
- Open a pull request
MIT © MIE