Standalone JSON/JSONC programming language engine. Embeddable in Go applications. Part of the BitCode platform but independently usable.
Pipeline: JSONC pre-process → JSON parse → import resolution → AST → compile (struct registration, structural validation, limit resolution) → immutable Program → VM execution with debug hooks.
Expression evaluation delegated to expr-lang/expr via ExprEngine abstraction layer. The VM never calls expr-lang directly.
Phase 4.5a design: docs/plans/2026-07-14-runtime-engine-phase-4.5a-go-json-core-language.md
Phase 4.5b design: docs/plans/2026-07-14-runtime-engine-phase-4.5b-go-json-modularity.md
Phase 4.5b plan: docs/plans/2026-07-14-runtime-engine-phase-4.5b-go-json-modularity-plan.md
Phase 4.5g design: docs/plans/2026-07-15-phase-4.5g-lambda-language-core.md
Decisions: docs/plans/2026-04-28-go-json-brainstorming-design.md
packages/go-json/
├── lang/ Core language engine (AST, parser, compiler, VM, scope, types, errors, expr engine, debugger, import resolver)
├── stdlib/ Layer 2 stdlib (135+ functions + crypto/validate namespaces + regex + path + JSON + env + higher-order). Layer 1 = expr-lang built-ins (~68 functions)
├── runtime/ Runtime API: NewRuntime(), Execute(), ExecuteFunction(), CompileFile(), Close(), program cache, limits, logger, session, extensions. Also: EvalExpr(), EvalExprBool(), EvalExprFloat(), ParseExpr(), ValidateExpr() — lightweight expression evaluation API for engine consumers (shared singleton ExprLangEngine with stdlib + compilation cache).
├── io/ I/O modules: HTTP, FS, SQL, Exec, MongoDB, Redis with security layer + unified SQL param translation (Phase 4.5c-d)
├── codegen/ Code generation: Go/JS/Python generators + server codegen (Fiber/net-http/Express/FastAPI) + dependency management (Phase 4.5c-d)
├── server/ Web server execution mode: adapters (Fiber/net-http/Echo/Gin/Chi), middleware, JWT, auth, templates, static, OpenAPI (Phase 4.5d)
├── server/adapters/ Framework adapter implementations (ServerAdapter interface)
├── generate/ CRUD generator, auth scaffold, project scaffold, pattern templates, DB introspection (Phase 4.5d)
├── cmd/go-json/ CLI: run, serve, check, test, ast, codegen, generate, openapi, migrate commands
└── testdata/ Test fixture programs (.json, .jsonc)
- ExprEngine abstraction — VM never calls expr-lang directly. All expression work goes through
ExprEngineinterface for testability and swappability. - Compile-once, run-many —
CompiledProgramis immutable after compilation. Each execution gets fresh VM + scope. Multiple goroutines can run the same program concurrently. - Structural validation at compile time, expression validation at runtime — expr-lang's compile-time type checking requires a fully-typed environment which we don't have with gradual typing. Runtime catches expression errors.
- Scope isolation for functions and methods —
IsolatedChild()creates scope WITHOUT parent link. Functions and methods cannot access caller variables.selfis injected into method scope. Block scope (NewChild()) for if/for/while allows reading and mutating outer variables. - Sentinel types for control flow —
returnValue,breakSignal,continueSignalare unexported struct types that propagate throughexecuteSteps()return values. - Resource limits at every step — step count, call depth, loop iterations, timeout checked before each step execution. MaxVariables, MaxVariableSize checked after every
Declare(). MaxOutputSize checked on program return. - JSON param ordering — Go maps don't preserve insertion order.
extractOrderedKeys()usesjson.Decodertokenization to recover function param order from raw JSON. - Built-in name protection —
letblocks variable names that shadow critical built-in functions (len, abs, min, max, etc.). Curated list excludes common-word functions (count, filter, sort) that are also natural variable names. - Implicit scope variables —
session.*(user_id, locale, tenant_id, groups) andexecution.*(id, program, started_at, depth, step_count) injected automatically into every execution. - Trace enrichment —
TraceEntrycaptures Var/Value for let/set, Condition/Result for if/while/switch, per step type viaenrichTraceEntry().
let, set, if/elif/else, switch, for (each + range), while, break, continue, return, call, try/catch/finally, error, log, parallel, match, sleep, retry, assert, _c (comment)
- Structs defined in
structsblock with fields, methods, optionalfrozen: true - Construction via
{"let": "x", "new": "StructName", "with": {...}} - Nested construction:
"field": {"new": "Other", "with": {...}} - Runtime type-checking on construction: field values validated against declared types (TYPE_MISMATCH error)
- Methods with implicit
selfbinding, callable at expression and step level - Frozen structs: compile-time rejection of
set "self.*"in methods selfreassignment blocked in all node types (if/for/while/try/switch/parallel)- Forward references resolved via two-pass compilation
- Circular non-nullable struct references detected at compile time
- Import key:
"import"(preferred) or"imports"(compat) - Path types: relative (
./), stdlib (stdlib:), extension (ext:), I/O (io:), script (script:), WASM (wasm:), native plugin (plugin:) - Imported items namespaced via alias:
alias.StructName,alias.functionName - Circular import detection via import stack
- Import alias collision detection (compile error on duplicate namespaced names)
- Barrel file re-export via
{"alias": "imported.Type"}in structs block - Diamond imports handled correctly (loaded once, cached)
- Wired via
Runtime.CompileFile(path)— import resolution between parse and compile - Script imports (
script:./path.py) — resolved at runtime viaScriptRuntimeinterface (Phase 4.5j) - WASM imports (
wasm:./plugin.wasm) — resolved via.wasmextension to WASM runtime (Phase 4.5k) - Native plugin imports (
plugin:./plugin.so) — resolved via.so/.dylibextension to native runtime (Phase 4.5k)
ScriptRuntimeinterface inruntime/script_runtime.go— defines contract for external script enginesScriptRuntimeRegistry— manages multiple runtimes, resolves by file extensionWithScriptRuntime(rt)/WithScriptBridge(bridge)— runtime optionsscript:imports recorded inRequestedModules, resolved at execution time- Script proxy injected as
map[string]any{"call": fn, "exec": fn}— expression-level:ml.call("predict", data) - Step-level calls:
{"call": "ml.call", "with": ["'predict'", "data"]}via existing namespace function dispatch - Path validation: absolute paths rejected, traversal prevented via
filepath.Clean+ prefix check SourcePathfield onProgramAST — set byCompileFilefor relative path resolution- go-json core remains zero-dependency —
ScriptRuntimeis interface only - Implementations live in
packages/go-json-runtimes/(separate go.mod)
{"parallel": {"branch1": [...], "branch2": [...]}, "into": "results"}- Each branch gets own VM + scope (read parent, cannot write parent)
- Compile-time check:
settargeting parent variable in parallel branch = error - Join modes:
all(default, wait for all),any(first success wins),settled(wait for all regardless of errors, errors collected as error objects) - Error modes:
cancel_all(default),continue,collect - Goroutine leak prevention: drain channel after cancel
- Shared step counter across branches via
sync/atomic— prevents step limit bypass via many parallel branches - Struct instances are NOT thread-safe — do not share mutable struct instances across parallel branches
| Layer | Contents | Ownership |
|---|---|---|
| Layer 1 | expr-lang built-ins (~68 functions: abs, ceil, floor, round, min, max, len, upper, lower, trim, split, filter, map, reduce, find, sort, int, float, string, type, etc.) | expr-lang — DO NOT reimplement |
| Layer 2 | go-json additions (135+ functions + crypto/validate namespaces). Phase 4.5a: clamp, sign, randomInt, randomFloat, pow, sqrt, mod, padLeft, padRight, substring, format, matches, append, prepend, slice, chunk, zip, bool, isNil. Phase 4.5b: has, get, merge, pick, omit, formatDate (universal format), addDuration, diffDates, urlEncode, urlDecode, sprintf, crypto.sha256, crypto.md5, crypto.uuid, crypto.hmac. Phase 4.5d: toJSON, fromJSON, basename, dirname, extname, joinpath, cleanpath, isabs, stemname, pathsep. Phase 4.5f: capitalize, title, camelCase, snakeCase, kebabCase, pascalCase, truncate, slugify, strReverse, strCount, replaceFirst, lines, words, isDigit, isAlpha, isAlphaNum, isEmpty, isBlank, escapeHTML, unescapeHTML, sin, cos, tan, asin, acos, atan, atan2, log, log2, log10, exp, trunc, random, isNaN, isInfinite, isFinite, PI, E, Infinity, NaN, toUnix, fromUnix, toISO, startOfDay, endOfDay, startOfMonth, endOfMonth, isWeekend, isBefore, isAfter, daysInMonth, isLeapYear, compact, includes, arrayIndexOf, keyBy, difference, intersection, union, fill, drop, takeRight, flatMap, partition, deepMerge, deepClone, deepEqual, setIn, deleteIn, defaults, mapKeys, mapValues, toFixed, formatNumber, formatBytes, formatPercent, env(), validate.isEmail, validate.isURL, validate.isIP, validate.isUUID, validate.isJSON, validate.isNumeric, validate.isAlpha, validate.isBase64, validate.isHexColor, validate.isCreditCard, crypto.sha512, crypto.encrypt, crypto.decrypt, crypto.hashPassword, crypto.verifyPassword, crypto.randomBytes. Phase 4.5g: mapFn, filterFn, rejectFn, reduceFn, findFn, everyFn, someFn, sortFn, takeWhileFn, dropWhileFn, partitionFn, applyEach, identity | stdlib/ package |
| Layer 3 | I/O modules (HTTP, FS, SQL, Exec, MongoDB, Redis, Cache, Email) with two-layer security gating. Regex stdlib (match, findAll, replace with LRU caching). FS enhancements: stat, copy, move, glob. SQL unified query parameter translation (?/:name across drivers). Cache: in-memory key-value with TTL + cleanup goroutine. Email: SMTP with STARTTLS + env var config. | io/ and stdlib/regex.go |
- Follow root
AGENTS.mdconventions (no unnecessary comments, tests required) - All exported types and functions need Go doc comments
go build ./...andgo vet ./...must pass- Tests:
go test ./... -v
cd packages/go-json
go test ./... -v # All tests (1018)
go test ./lang/ -v # Language engine tests
go test ./lang/ -run TestStruct -v # Struct tests
go test ./lang/ -run TestMethod -v # Method tests
go test ./lang/ -run TestParallel -v # Parallel tests
go test ./lang/ -run TestImport -v # Import tests
go test ./lang/ -run TestIntegration -v # Integration tests
go test ./stdlib/ -v # Stdlib tests (including regex, path, JSON)
go test ./io/ -v # I/O + SQL param translation tests
go test ./runtime/ -v # Runtime + extension tests
go test ./codegen/ -v # Code generation + server codegen tests
go test ./server/ -v # Server config, routing, handler, auth, JWT, middleware, OpenAPI, template, static tests
go test ./generate/ -v # CRUD generator, auth scaffold, project scaffold, introspection, pattern tests- Struct definitions with fields, defaults, frozen, methods
- Struct construction (
new+with), nested construction, return with new - Method system with
selfbinding, mutation, frozen compile-time check - Import system with relative file resolution, circular detection, barrel files
- Parallel execution with 3 error modes, scope isolation, compile-time parent write check
- Stdlib Layer 2 extensions: maps, datetime, encoding, crypto (namespaced), format
- Nullable type support (
?T), optional chaining via expr-lang
- I/O module framework:
IOModuleinterface,IORegistry,WithIO()/WithoutIO()runtime options - I/O security layer:
SecurityConfig, two-layer gating (import + runtime enable), hardcoded deny lists, path traversal prevention, cloud metadata blocking - HTTP module: GET/POST/PUT/PATCH/DELETE with auth (bearer/basic), redirect following, response size limits, client reuse
- FS module: read/write/append/exists/list/mkdir/remove with sandboxing, encoding (UTF-8/base64), symlink resolution
- SQL module: query/execute with connection pooling per-DSN, DefaultDSN, multi-driver detection (postgres/mysql/sqlserver/oracle/sqlite), transactions with savepoints, DDL protection (blocked keywords + max query length), auto-rollback on Close/Cleanup
- Exec module: command whitelisting, DeniedCommands (always blocked), env isolation, EngineSecrets stripping, output truncation
- MongoDB module: find/findOne/insert/insertMany/update/delete/count/aggregate with NoSQL injection protection ($where/$function blocking), security config (AllowedDatabases, MaxDocumentSize, MaxResults, MaxPools)
- Redis module: get/set/del/exists/expire/ttl/incr/decr/hget/hset/hgetall/lpush/rpush/lrange/sadd/smembers/publish with auto JSON serialize/deserialize, KeyPrefix tenant isolation, blocked commands (FLUSHALL, CONFIG, etc.)
- Regex stdlib: match/findAll/replace with LRU cache (max 1000 patterns), ReDoS prevention
- Extension API:
Extensionstruct with Functions/Structs/Constants,WithExtension()runtime option,ext:nameimport support - Import resolver:
io:andext:imports recorded inRequestedModules, validated at runtime (two-layer security enforced) - Runtime.Close(): propagates to all I/O modules implementing Close() error
- Bitcode bridge adapter: nested namespace maps for dotted access (bc.db.query), explicit type errors instead of silent coercion, optimized convertToAny
- GoJSONRunner: uses CompileFile for proper import resolution
- scripts/*.json support:
detectRuntimeFromExtensiondetects.json→go-json,GoJSONRunnerimplementsEmbeddedRunner - Backward compatibility:
ProcessDefinition.Runtimefield,IsGoJSON()helper, old format unchanged - Process engine data step replacement:
GoJSONDataHandleradapts old step types to bridge calls - CLI: run (--input/--input-file/--timeout/--io/--trace/stdin), check (--verbose), test (--filter/--verbose), ast (--output), codegen (--target/--output/--package), migrate (--from/--to/--dry-run, JSON-aware key renaming)
- Code generation:
CodeGeneratorinterface, Go/JavaScript/Python generators handling all step types including new/import/expression/switch - Windows path security: case-insensitive matching, directory boundary checks,
filepath.Rel-based AllowedPaths validation - Security: AllowedHosts explicitly override BlockedHosts (explicitly allowed hosts skip blocked check)
- Exec timeout: context deadline check prioritized over ExitError for reliable timeout detection
- MongoDB module: real driver (
go.mongodb.org/mongo-driver/v2), lazy connection, full CRUD + aggregation - Redis module: real driver (
github.com/redis/go-redis/v9), lazy connection, 16 commands, auto JSON serialize - CLI:
go-json ast --formatflag (forward-compatible, json only for now) - 723 tests total across 10 packages (lang: 177, io: 132, stdlib: 103, server: 108, runtime: 79, generate: 48, cmd: 45, codegen: 36)
- Server execution mode (
go-json serve): declarative routing, plugable framework adapters, middleware, template rendering, static files - ServerAdapter interface: framework-agnostic abstraction with
RequestContext/Responsetypes, adapter registry - Framework adapters: Fiber (default), net/http (stdlib), Echo (build-tagged), Gin (build-tagged), Chi (build-tagged)
- Route system: declarative routes with groups, prefix nesting, middleware merging, route flattening, validation
- Handler bridge:
BuildHandlerconverts HTTP→go-json function→HTTP.ExecuteFunctionadded to Runtime and VM for direct function invocation - Request object: full body parsing (JSON, form, multipart, text), file upload with temp file handling + cleanup, path params, query, headers, cookies, IP, store
- Response convention: status+body (JSON), data+render (template), redirect, cookies, headers, error field, 204 for nil
- Middleware chain engine: built-in (logger, recover, CORS, secure headers, request_id, compress, rate_limit) + custom go-json functions with short-circuit
- JWT module: middleware (header + cookie extraction, validation) + callable functions (sign, verify, decode, refresh)
- Plugable auth system:
AuthStrategyinterface with Bearer/JWT, API Key, Basic Auth, Custom (go-json function) strategies.authandauth:namemiddleware resolution - Template engine: Go html/template with 20+ built-in functions (json, formatDate, upper, lower, truncate, default, safeHTML, urlEncode, add/sub/mul/div/mod, seq, etc.), layouts, partials, dev-mode reload
- Static file serving: configurable directory + prefix, path traversal protection, hidden file blocking
- OpenAPI/Swagger: auto-generated OpenAPI 3.0 spec from routes,
apiannotation support (body/query/responses), security scheme mapping, Swagger UI at/docs,go-json openapiCLI command - Server codegen:
ServerCodegenAdapterinterface with language×framework registry. Implementations: Go+Fiber, Go+net/http, JS+Express, Python+FastAPI - Codegen dependency management: feature detection, go.mod/package.json/requirements.txt/.env.example generation
- SQL unified query parameters:
TranslateQueryconverts?and:nameplaceholders to driver-specific syntax (postgres $1, sqlserver @p1, oracle :1, sqlite/mysql ?). Integrated into SQL module - FS enhancements: fs.stat, fs.copy, fs.move, fs.glob + enhanced fs.list
- Path stdlib: basename, dirname, extname, joinpath, cleanpath, isabs, stemname, pathsep
- Stdlib additions: toJSON/fromJSON, formatDate universal format (YYYY-MM-DD → Go layout translation)
- CRUD generator: database introspection (SQLite, PostgreSQL, MySQL), type mapping (DB→go-json→OpenAPI), manual fields mode, CRUD route+handler generation with validation
- Auth scaffold generator: register, login, refresh, me, change-password endpoints with JWT
- Project scaffold generator: full project structure (api.json, templates/, public/, migrations/, .env.example, README.md)
- Pattern template engine: built-in patterns (simple, service-layer, DDD, hexagonal), custom template support, per-model file generation
- CLI commands:
go-json serve(--dev, --port, --host, --docs, --io),go-json generate(crud/auth/project with --table/--fields/--dsn/--auth/--output),go-json openapi(--output) - Server mode detection:
IsServerProgram()checks for routes key - Health endpoint: built-in
/healthwith status, name, uptime (bypasses middleware) - Graceful shutdown: SIGINT/SIGTERM handling with configurable timeout
- 723 tests total across 9 packages (includes Phase 4.5a–d cumulative)
- Pattern templates: 4 built-in patterns (simple, service-layer, ddd, hexagonal) with actual template files
- Lambda expressions:
fn(params) => body(anonymous) andfn name(params) => body(named, recursive) - Named recursive lambda: self-reference via forward-declared closure, depth-limited by
vm.limits.MaxDepth - Pattern matching:
matchstep with structural patterns, variable binding ($var), wildcards (_,$_), guards (when), subset map match - Lambda preprocessing: standalone lambda detection, inline lambda extraction, placeholder replacement
- Higher-order functions:
mapFn,filterFn,reduceFn,applyEach,sortFn— accept callable lambdas - Dynamic call_ref:
callresolves variable containing function name (string) or callable (lambda) - Sleep step:
{"sleep": ms}with literal or expression duration, context cancellation, 5-minute max - Retry step:
{"retry": {steps, max, delay, backoff}}with fixed/linear/exponential backoff - Assert step:
{"assert": "condition", "message": "..."}— throws ASSERTION_FAILED on false - Constants block:
"constants": {...}— immutable values, compile-time reassignment protection - Enum system:
"enums": {...}— array enums (value=value) and map enums (key=value), dot access - Enhanced test runner:
expect_error,before/after,skip/only,table(parameterized), per-case timeout - Codegen updates: sleep/retry/assert generation for Go, JavaScript, Python
- 969 tests total across 9 packages (includes Phase 4.5a–g cumulative)
- Cache module (
io:cache): in-memory key-value cache with TTL, background cleanup goroutine (60s interval), security limits (MaxEntries, MaxValueSize, MaxTTL), goroutine-safe (RWMutex), lazy eviction on read, double-close safe - Email module (
io:email): SMTP client with STARTTLS, env var fallback (SMTP_HOST/PORT/USER/PASSWORD/FROM/TLS), runtime SetConfig(), security (AllowedRecipients glob, BlockedDomains, MaxBodySize, MaxRecipients), IPv6-safe (net.JoinHostPort) - Both modules follow
IOModuleinterface, registered inAll(), security configs in unifiedSecurityConfig - 1018 tests total across 9 packages (includes Phase 4.5a–i cumulative)
- Expression-level compile-time type validation (deferred to runtime)
- MongoDB/Redis require running servers for actual I/O (tests use miniredis for Redis, security-only tests for MongoDB)
- REPL mode (future)
- Dev mode file watching (fsnotify — optional dependency, not yet added)
- Interactive mode for
go-json generate(--interactive flag)