The frontend framework for correctness. Documentation · Why Foldkit · Examples · Get Started · Discord --- Foldkit is a TypeScript frontend…
The frontend framework for correctness. Documentation · Why Foldkit · Examples · Get Started · Discord --- Foldkit is a TypeScript frontend…
The frontend framework for correctness.
Documentation · Why Foldkit · Examples · Get Started · Discord
Foldkit is a TypeScript frontend framework built on Effect. It gives your entire application one architecture: a Schema-defined Model as the single source of truth, fact-named Messages, an exhaustive update function, and explicit Commands for side effects. Routing, server rendering, UI components, Submodels, and browser lifecycles all use that same Model and Message flow.
Foldkit uses The Elm Architecture instead of component-owned state and hook lifecycles. That discipline is a real commitment. Foldkit works best when the team wants shared conventions across the application and is ready to build on Effect throughout. If your backend already uses Effect, Foldkit carries the same tools and patterns into the browser: Schema, services, Streams, and scoped resources.
A Foldkit program can own the whole page or run as a widget inside an existing application, React included, through Runtime.embed. The same program can render on the server at build time or per request, then hydrate in place. Coming from React? Start here, or compare the same pixel-art editor built in both frameworks.
[!NOTE] Foldkit is in beta and under active development. The core API is stable, but breaking changes may occur in minor releases. See the changelog for details.
create-foldkit-app scaffolds a complete setup with Tailwind, TypeScript, Oxlint, Oxfmt, and the Vite plugin for state-preserving live reload. Pick a rendering mode (browser-only SPA, static generation, or server rendering) and, for a SPA, the example to start from.
npx create-foldkit-app@latestA complete Foldkit program. State lives in a single Model, events become Messages, and a pure function handles every transition. main.ts defines the program and entry.ts boots the Runtime, so main.ts stays importable from tests without booting a Runtime as a side effect.
…// src/entry.ts
import { Runtime } from 'foldkit'
import { Model, init, update, view } from './main'
const application = Runtime.makeApplication({
Model,
init,
update,
view,
container: document.getElementById('root'),
})
Runtime.run(application)Source: examples/counter.
Routing, server rendering, UI components, composition, and browser lifecycles all use the same Model and Message flow. The pieces below ship as one system and are documented in depth at foldkit.dev.
Got* envelope.Runtime.embed.@foldkit/ui package.Every feature has the same visible structure: a Schema-defined Model, fact-named Messages, exhaustive update, and explicit Commands. AI-generated changes follow code paths a person can inspect and test. Foldkit DevTools and its MCP server expose the same Model and Message history while the application runs.
Some of what you can build with Foldkit. See all example apps on foldkit.dev.
Building something for the Foldkit ecosystem? You're welcome to use the Foldkit name, logo, and visual language without advance permission. See the community branding guidelines.
See CONTRIBUTING.md for the checks, commit conventions, and changeset expectations, and AGENTS.md for code style.
git clone https://github.com/foldkit/foldkit.git
cd foldkit
pnpm install
# Build the Foldkit libraries in watch mode
pnpm dev:libs
# Run an example (in a separate terminal)
pnpm dev:example:counterExternal reference repositories under repos/ are vendored in as git subtrees, so they come down with the clone. Each is pinned to the release tag matching the version this repo depends on, not a moving branch, so the reference source always matches what installs and compiles. Refresh repos/effect from the effect@ tag that matches package.json, and re-pin it whenever the effect dependency is bumped:
VER=$(node -p "require('./packages/foldkit/package.json').devDependencies.effect")
git subtree pull --prefix=repos/effect https://github.com/Effect-TS/effect.git "effect@${VER}" --squashMIT
No open issues yet, or sync has not completed.