
Product
Socket Now Protects the Firefox Extension Ecosystem
Socket is bringing experimental protection to Firefox, scanning 97,000+ extensions in Mozilla's official directory for malware and risky updates.
Documentation · Manifesto · Examples · Getting Started · Discord
Foldkit is a TypeScript frontend framework built on Effect and architected like Elm. One Model, one update function, one way to do things. No hooks, no local state, no hidden mutations. It's all in on Effect with no escape hatch, though a program doesn't have to own the whole page: Runtime.embed runs a Foldkit widget inside any existing app, React included. The same program also renders on the server, at build time or per request, and hydrates in place.
Your Model is a Schema and side effects are values you return, not callbacks you fire. If you know Effect, Foldkit feels natural. If you're new to it, Foldkit is a good way in. Coming from React? Start here, or read the same pixel-art editor built in both frameworks.
[!NOTE] Foldkit is pre-1.0. 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, Prettier, and the Vite plugin for state-preserving HMR. 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@latest
A 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/main.ts
import { Match as M, Schema as S } from 'effect'
import { Command, Runtime } from 'foldkit'
import { Document, HtmlBuilder } from 'foldkit/html'
import { m } from 'foldkit/message'
import { evo } from 'foldkit/struct'
// MODEL
export const Model = S.Struct({ count: S.Number })
export type Model = typeof Model.Type
// MESSAGE
const ClickedDecrement = m('ClickedDecrement')
const ClickedIncrement = m('ClickedIncrement')
const ClickedReset = m('ClickedReset')
export const Message = S.Union([
ClickedDecrement,
ClickedIncrement,
ClickedReset,
])
export type Message = typeof Message.Type
// UPDATE
export const update = (
model: Model,
message: Message,
): readonly [Model, ReadonlyArray<Command.Command<Message>>] =>
M.value(message).pipe(
M.withReturnType<
readonly [Model, ReadonlyArray<Command.Command<Message>>]
>(),
M.tagsExhaustive({
ClickedDecrement: () => [evo(model, { count: count => count - 1 }), []],
ClickedIncrement: () => [evo(model, { count: count => count + 1 }), []],
ClickedReset: () => [evo(model, { count: () => 0 }), []],
}),
)
// INIT
export const init: Runtime.ApplicationInit<Model, Message> = () => [
{ count: 0 },
[],
]
// VIEW
export const view = (model: Model, h: HtmlBuilder<Message>): Document => ({
title: `Counter: ${model.count}`,
body: h.div(
[],
[
h.p([], [model.count.toString()]),
h.button([h.OnClick(ClickedDecrement())], ['-']),
h.button([h.OnClick(ClickedReset())], ['Reset']),
h.button([h.OnClick(ClickedIncrement())], ['+']),
],
),
})
// 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.
A complete system, not a collection of libraries you stitch together. Each of these is documented in depth at foldkit.dev.
Got* envelope.Runtime.embed.@foldkit/ui package.Every state change flows through one update function, and every side effect is declared explicitly. You don't have to hold a mental model of what runs when, you can point at it. That's what makes Foldkit unusually AI-friendly: the property that makes the code easy for humans to reason about makes it easy for an LLM to generate and review.
Some of what you can build with Foldkit. See all example apps on foldkit.dev.
MIT
FAQs
A TypeScript frontend framework, built on Effect and architected like Elm
The npm package foldkit receives a total of 9,385 weekly downloads. As such, foldkit popularity was classified as popular.
We found that foldkit demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Product
Socket is bringing experimental protection to Firefox, scanning 97,000+ extensions in Mozilla's official directory for malware and risky updates.

Research
/Security News
Three compromised Rust crates pulled in a malicious dependency that downloaded and executed cross-platform malware during Cargo builds.

Research
/Security News
Socket uncovered 77 linked Firefox extensions, including 40 that steal wallet secrets or credentials and 37 deceptive sports-score shells.