Generated Computers
Locals: an Apple Silicon engine that runs local LLMs up to 3x faster. A product of Generated Computers.
翻譯準備中
Low-code application builder for PostgreSQL: build data-driven web apps in SQL. An open source alternative to Oracle APEX.
翻譯準備中
取自儲存庫 README
正在載入完整 README。
檢視完整 README ↗Website · Documentation · Tutorial · Coming from Oracle APEX · Roadmap
A low-code, SQL-driven application builder for PostgreSQL, modeled on
Oracle APEX. Applications are data: pages, regions, items, buttons,
dynamic actions, validations and processes are rows in the meta schema. A
runtime turns those rows into web pages, and the builder is an editor for
them.
pgkiln is an independent open source project and is not affiliated with Oracle. Oracle and APEX are trademarks of Oracle.
Everything below is the HR example application (npm run example:hr) and the builder. The
screenshots are made by npm run screenshots.
| Dashboard: metric cards and charts, all of it SQL | Interactive report: search, filters, sort, download |
| Smart filters and faceted search | Map and cards regions on the same table |
| Charts, in dark mode | Calendar of leave requests |
| App Builder home | SQL Workshop: object browser with RLS and grants |
With Docker (no Node.js needed):
mkdir pgkiln && cd pgkiln
curl -fsSLO https://raw.githubusercontent.com/pgkiln/pgkiln/main/deploy/compose.yaml
curl -fsSL -o .env https://raw.githubusercontent.com/pgkiln/pgkiln/main/deploy/.env.example # fill in the four secrets
docker compose up -d # http://127.0.0.1:3100/builder (admin / the password from .env)
Or from the source, for developing:
npm install
cp .env.example .env
npm run setup # Postgres 17 on localhost:5434 + the pgkiln schema (migrations)
npm run dev # http://127.0.0.1:3100/builder (admin / admin)
Then build an application on your own tables: Create application in the builder generates report and form pages from a table, and everything else (regions, items, processes, security, translations, documents, approvals) is added in the page designer and Shared Components. The tutorial walks through one.
pgkiln itself contains no application. The repository ships an example built on it, HR
(examples/hr/): employees and departments, leave requests with approvals, a dashboard, a REST API,
translations, documents, automations and row level security, all of it ordinary pgkiln metadata
and PostgreSQL code, the way you would build your own.
npm run example:hr # http://127.0.0.1:3100/a/hr
Users (password = username): king is admin and manager (the president), blake and jones are
managers, allen and scott are employees, and demo is an admin who is not an employee. Sign
in as different users to see authorization schemes and row level security at work.
npm test # unit + security regression tests (installs the HR example as their fixture)
npm run test:e2e # browser tests on phone/tablet/desktop (npx playwright install chromium first)
npm run db:reset recreates the database (pgkiln only). Schema changes go in a new
db/migrations/NNN_*.sql file; npm run db:migrate applies pending ones.
pgkiln ships an MCP server (pgkiln mcp), so Claude Code, Cursor and other agents can find an
application, read and explain its pages, look at the tables and RLS policies behind them, search
this documentation, and change the application: export it as files (one YAML file per component,
SQL inline), edit them, show the diff, and import them again in one transaction. In a checkout,
.mcp.json starts it for Claude Code; for your own project:
claude mcp add pgkiln -- /path/to/pgkiln/bin/pgkiln.js mcp
Without a checkout, npx -y pgkiln mcp (with DATABASE_URL set) or, for the Docker installation,
docker compose exec -T pgkiln node bin/pgkiln.js mcp starts the same server.
Then ask things like "explain what happens when I press Save on page 3 of hr" or "add a hire date column to the employee report and show me the diff". Queries it runs are read-only. See AI coding agents.
Without an agent, the same export and import is on the command line (pgkiln export hr --format text,
pgkiln diff, pgkiln import --replace, see the CLI) and in the builder
(Export / Import).
What's next: ROADMAP.md.
The user guide explains how everything works: installation and configuration, concepts, the builder, every region and item type, processing, dynamic actions, security, the SQL reference, a step-by-step tutorial, a guide for Oracle APEX developers, and developing pgkiln itself.
For a full comparison with Oracle APEX 26.2, including what's missing, see docs/apex-feature-parity.md.
Runtime (Universal Theme-style UI, responsive on phone, tablet and desktop)
STATIC: or shared lists; items can be required or read-only (by condition), and select lists can cascade.Builder
pgkiln command line: migrations, export/import, and apps as one file per component for git
(diff, update in place)pgkiln mcp): read, explain, change, diff and import applicationsSecurity is covered in SECURITY.md: least-privilege runtime role, per-app database roles, authorization schemes, checksummed URLs and grid rows, CSRF protection, login throttling, a strict CSP, and 28 security regression tests.
The example (examples/hr/hr.sql) keeps its business rules in
the database and calls them from the app:
| Where in the app | Database object | Shows |
|---|---|---|
| Leave requests → Submit request | hr.request_leave() | Validation in PL/pgSQL (dates, overlaps, a 25-day balance). raise exception … using column = 'end_date' puts the message on the matching form field. |
| Leave request → Approve / Reject | hr.decide_leave() | Authorization in the database: a recursive CTE checks the management chain (hr.is_manager_of). |
| Manager's dashboard, employee's dashboard | hr.notify_leave_requested(), hr.notify_leave_decided() | Triggers creating notifications for other users (SECURITY DEFINER past RLS) |
| Employee form → Give 10% raise | hr.give_raise() | Role check via meta.has_role(); the returned salary is written back into the item |
| Employee form, salary field | trigger hr.check_salary() | A BEFORE trigger rule whose error appears on the Salary field |
| Employee form, Job | hr.suggest_salary() | Dynamic action: set a value from SQL as you type |
| Leave form, dates | hr.business_days() | Dynamic action computing working days live |
| Administration → Audit trail | trigger hr.audit() | A generic jsonb-diff audit trail recording the application user |
| Leave requests, notifications, audit | RLS policies | Each user sees only their own and their team's rows |
| Sign in | after-login application process | Maps the app user to an employee (AI_EMPNO, AI_ENAME) |
Browser ── HTML + /static/app.js (dialogs, dynamic actions; no inline JS)
│
Runtime (Fastify, server-rendered) Builder (/builder)
│ per request: BEGIN │ owner connection
│ set pgkiln.app_user / app_id / session │ edits meta.* rows
│ SET LOCAL ROLE <app db_role> │ SQL Workshop
│ authorization → visibility → render/process
│ COMMIT
│ connects as pgkiln_runtime (least privilege)
Postgres
meta.* app definitions, sessions (hashed tokens), activity log
your schemas tables, PL/pgSQL, RLS policies
:NAME in developer SQL is replaced by the item's value as an escaped,
untyped string literal. Postgres then resolves the literal's type from its
context, the way Oracle converts types implicitly. APEX patterns like
where :P2_DEPTNO is null or deptno = :P2_DEPTNO therefore work. With $1
parameters they fail with could not determine data type of parameter.
Empty strings are NULL, as in APEX. The scanner skips literals,
identifiers, comments, dollar quotes and :: casts (see test/binds.test.ts).
Inside functions and DO blocks, use meta.v('P1_X').
| Function | Purpose |
|---|---|
meta.app_user() | Signed-in application user (nobody when anonymous) |
meta.has_role('admin') | Role check; use it in RLS policies |
meta.v('P1_ITEM') | Session state value |
meta.page_url(3, '{"P3_ID": 7}') | Link with a valid checksum |
meta.generate_crud('app', 'schema.table', 2, 3) | The page wizard |
meta.generate_page('app', 'calendar', 'schema.table', 4) | The other page wizards (form, cards, calendar, chart, map, facets, master_detail) |
meta.export_app('alias') / meta.import_app(json) | Deployment (or pgkiln export / pgkiln import, chapter 18) |
db/migrations/ pgkiln: versioned schema (metadata repository, roles, SQL API)
examples/hr/ an example application built on pgkiln (not part of it): schema, PL/pgSQL, RLS, app definition
src/runtime/ context, authz, items, report, grid, charts, calendar, facets, regions, render, engine, routes
src/builder/ builder UI; components.ts is the spec the property editor is generated from
src/security.ts checksums, headers, password policy
src/cli/ the `pgkiln` command line (bin/pgkiln.js; docs/guide/18-cli.md)
public/ theme (CSS), app.js, icon sprite
test/ bind scanner unit tests, security regression tests, e2e/ browser tests
See the prioritised roadmap at the end of docs/apex-feature-parity.md.
Contributions are welcome. Read CONTRIBUTING.md and the Code of Conduct, and report vulnerabilities privately as described in SECURITY.md.
Copyright 2026 Vargar. Licensed under the Apache License, Version 2.0.