Free and open-source pseudo code editor and compiler.
Free forever, open source always. Build your pseudo code project freely and creatively.
pseudoeditor.dev · Practice · Docs · Manual · Security · Apache-2.0
PseudoEditor lets you write structured pseudocode, compile it with line-level diagnostics, run it in your browser, and view it as a flowchart. Everything runs client-side in WebAssembly. Signing in is optional and only enables cloud workspace sync.
| Path | What it is |
|---|---|
apps/web |
Next.js website and browser editor (@pseudoeditor/web) |
packages/compiler |
TypeScript tokenizer, parser, and AST compiler (@pseudoeditor/compiler) |
packages/workspace |
Workspace model, validation, and persistence helpers (@pseudoeditor/workspace) |
packages/pseudocode-runtime |
Rust runtime compiled to WebAssembly |
convex |
Convex schema, workspace sync functions, and Clerk webhook |
scripts |
Build scripts |
The site and editor ship in English (/) and Simplified Chinese (/zh). Locale routing lives in
apps/web/src/proxy.ts, UI strings in apps/web/src/i18n/messages/, docs and blog content in
apps/web/src/lib/seo-content*.ts, practice questions in apps/web/src/lib/practice-questions*.ts,
and legal pages in content.en.tsx / content.zh.tsx next to each page.
Every page emits hreflang alternates and the sitemap lists both locales.
Requires Node 22 (see .nvmrc, minimum 20.9), pnpm 10 and, for runtime tests, Rust.
pnpm install
pnpm dev # http://localhost:3000
pnpm test # vitest in every package + cargo tests for the runtime
pnpm test:coverage # vitest with a coverage report
pnpm typecheck # strict TSRS checks: packages, web app and convex/
pnpm lint # eslint, zero warnings allowed
pnpm buildOn localhost the editor saves to browser storage and no account is required.
Type checking uses the pinned Rust-based TSRS compiler. Production builds run the
same checker against generated Next.js route types; type errors still stop the
build. pnpm typecheck:tsc keeps the TypeScript checker available for comparison.
See performance measurements for before/after results and
repeatable benchmarks.
CI (.github/workflows/ci.yml) runs the same checks on every push and pull request, plus
cargo clippy -D warnings and a rebuild of the WebAssembly runtime whose JS bindings must match the committed files.
- Create a Clerk application and a Convex project.
- Copy
.env.exampletoapps/web/.env.localand fill in the Clerk keys. - Run
npx convex devto link the Convex project (it writesNEXT_PUBLIC_CONVEX_URL). - In the Convex dashboard set
CLERK_JWT_ISSUER_DOMAINto your Clerk Frontend API URL andCLERK_WEBHOOK_SECRETto the signing secret of a Clerk webhook that targets<your-convex-site-url>/clerk/webhookfor theuser.createdanduser.deletedevents. - In Clerk, add a JWT template named
convex.
Requires the wasm32-unknown-unknown Rust target (the script adds it with rustup) and
wasm-bindgen CLI 0.2.121, which must match the wasm-bindgen version in Cargo.lock:
cargo install wasm-bindgen-cli --version 0.2.121 --locked
pnpm build:runtime # writes apps/web/src/runtime/wasm/pkgThe site deploys to Vercel with vercel.json, which runs scripts/vercel-build.sh to deploy
Convex functions and build the web app in one step. Required Vercel environment variables:
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY, CLERK_SECRET_KEY, and CONVEX_DEPLOY_KEY. .env.example
lists every variable and where it is set. Scope the production CONVEX_DEPLOY_KEY to the Production
environment only: if a Preview build sees a prod: key, the script skips convex deploy and only
builds the web app.
Analytics and error tracking use PostHog US Cloud and are enabled only when NEXT_PUBLIC_POSTHOG_KEY is set on
the Production environment. In the PostHog project, turn on Settings > Project > Web analytics > Enable
cookieless tracking, or PostHog drops every event the site sends. Keep session replay off, and set event
retention to one year or less to match the privacy policy.
Account counts come from Convex, not the browser. Each production build copies NEXT_PUBLIC_POSTHOG_KEY to
the production Convex deployment as POSTHOG_PROJECT_KEY, and copies CLERK_WEBHOOK_SECRET when it is set in
Vercel, so set both in Vercel's Production environment rather than on Convex. The Clerk webhook then sends anonymous account_created and account_deleted
events, and a daily cron (convex/crons.ts) sends account_stats: the number of synced accounts and how many
saved their workspace in the last 1, 7, and 30 days. None of these events identify an account.
pnpm.overrides in the root package.json holds only what a fresh resolve still needs:
| Override | Why |
|---|---|
dompurify ^3.4.17 |
monaco-editor 0.55 pins dompurify 3.2.7, which has XSS advisories fixed in 3.4.14 and later (for example GHSA-55q2-fjhq-7xh7; 3.4.17 closes later bypasses). Remove it once Monaco ships a patched version. |
source-map-js ^1.2.2 |
next 16.4.3 still resolves postcss's source-map-js 1.2.1, which allows event-loop denial of service (GHSA-68fv-2mgg-jv7q), fixed in 1.2.2. Remove it once Next ships a postcss with the patched range. |
Check with pnpm audit before adding or removing an override.
Issues and pull requests are welcome at https://github.com/The1UNeed/pseudoeditor.dev. Please report security problems privately as described in SECURITY.md.
Copyright 2026 Alex Xin LIU. Licensed under the Apache License 2.0. See LICENSE and NOTICE.