Release Notes

This page tracks what ships in the current Reepolee release line. Reepolee is pre-1.0, so documentation describes the current code. When you adopt changes from a newer version, use Reesync to review and select the files that belong in your project.

Reepolee uses calendar versioning, Ubuntu-style. A release is YY.MM.N - two-digit year, two-digit month, and the release number within that month. 26.07.1 is the first release shipped in July 2026. The version tells you when a release shipped, not what kind of change it carries; there is no semver-style major/minor/patch signal. The shape:

  • Month releases (26.07.1 → 26.08.1) - the first release of a new month is a feature release.
  • Point releases (26.07.1 → 26.07.2) - later releases within the same month may contain fixes or documentation updates.

Each entry below records what shipped in that release.

Versioning and Distribution

Reepolee isn't published to a package registry. There's no npm install reepolee. Clone the public repository and use its tagged releases to identify the version you are working with. package.json tracks the version for diagnostic purposes (it appears in props.version and on the production logs); bun pm version patch --no-git-tag-version bumps the YY.MM.N version in package.json.

During beta, tagged GitHub releases identify snapshots of the code documented here.

How to Stay Informed

Three ways to know when a new release ships:

  • GitHub releases - every release tag publishes notes on github.com/reepolee/reepolee/releases. Watching the repository (with the "Releases only" option) sends an email per release.
  • The production branch on this docs repo - when these release notes are updated, that's a release. Subscribing to the RSS feed of the docs site changelog covers it.
  • Following @reepolee on Twitter - release announcements with one-paragraph summaries, no other noise.

For deeper "what's about to ship" visibility, the Roadmap tracks larger initiatives in flight.

26.09 - Current

The 26.09 line is the current release. The latest tagged release documented here is 26.09.13. Highlights:

  • Server-rendered Ree templating with layouts, partials, and components (ReeTags). See Ree Templates.
  • Bun's native SQL for SQLite and MySQL with a single db instance imported from config/db.ts. The driver is a one-line file copy. See Database.
  • A complete CRUD generator that introspects your database and produces routes, queries, validation, templates, and translations from the schema alone. See Generators.
  • Invite-only authentication with sessions in the database, a small KV abstraction so the session store is swappable, and tags for authorization. See Authentication.
  • Tailwind v4 styling with design tokens in @theme, semantic utilities (primary/secondary/tertiary), and form-control defaults that mean templates rarely need per-input class lists. See Styling.
  • Full internationalisation - file-backed translations and localised URLs generated automatically from route_name translation keys. See Internationalization.
  • Optional client-side enhancements - fine-grained reactivity with the vendored alien-deepsignals bundle, native <details> and <dialog> patterns, focused form and dialog scripts, and a small set of shipped web components. See Client-Side UI Patterns.
  • Production-ready deployment with a systemd unit and Nginx configuration documented end-to-end. See Deployment.

Everything in the documentation reflects what the current 26.09 release ships.

Also included

The rest of what this release ships:

  • 26.09.13 opt-in queued Web Push notifications - with a VAPID key pair in .env (WEB_PUSH_PUBLIC_KEY / WEB_PUSH_PRIVATE_KEY / WEB_PUSH_SUBJECT), logged-in users get an Enable notifications button on framework pages, and application code can reach a user's subscribed browsers through queue_web_push_notification(). Subscriptions are stored per user in a new web_push_subscriptions table; delivery is encrypted (RFC 8291) and handled by the background worker as a web_push queue job, so HTTP requests only enqueue. See Web Push Notifications.

  • 26.09.13 cn() class merging in templates - the vendored Tailwind class-merge utility is exposed to Ree templates as a built-in cn(...) helper: it joins conditional class strings and keeps the winning utility when two classes target the same property, resolved during server-side rendering with no client JavaScript. See Helpers & Globals.

  • 26.09.11/26.09.12 reeman admin polish - Reeman pages set localized browser-tab titles, the Tables index hides internal _-prefixed system tables by default (with an all-tables toggle), and the column editor gained a form flag that omits a column from generated form inputs (form: false in config.ts). A stale tags-field translation expression that could crash at render time is repaired on refresh.

  • 26.09.10 external dev client scripts - the live-reload, inspector, and issue-reporter clients are served as external files from /__ree_client/<name>.js instead of being streamed inline into every dev page - smaller page HTML, real named script entries and working breakpoints in the browser debugger, and no-store caching so an edit applies on the next reload. See Dev Inspector.

  • 26.09.9 separate MySQL credentials - MySQL connection strings no longer embed credentials. Each environment (dev / prod / test) takes a credential-free endpoint in <ENV>_CONNECTION_STRING plus separate <ENV>_DB_USERNAME / <ENV>_DB_PASSWORD variables, so a secret manager can supply credentials without touching the endpoint. A string that still contains a username or password exits with an error. See Configuration and Database.

  • 26.09.9 MCP inspection on the dev connection - the MCP server's MySQL inspection now uses the development connection; the MCP_READONLY_CONNECTION_STRING variable is removed. SQLite inspection still opens a separate read-only connection. See MCP Server.

  • 26.09.9 localized input text - plain localized text fields now render through the dedicated <localized-input-text> component with a per-field reset-to-default button, and pressing Enter in a localized input activates the form's Save button instead of the reset action. See Localized Content.

  • 26.09.8 flattened generated route schema files - generated CRUD routes keep their schema files at the route root: config.ts (user-editable route settings), schema.generated.ts (auto-generated field definitions and TS types), and validation_server.ts (server-side Zod validation). The former schema/table.ts / schema/schema.generated.ts / schema/validation_server.ts layout is gone. See Generators.

  • 26.08.165 Studio DDL editor - the optional Studio module adds a browser editor for allowlisted SQLite and MySQL schema files. It provides canonical domain types, DDL previews, validated table actions, generated companion views, and a safe Adapt Schema action that writes a reviewed sibling copy. See Studio.

  • 26.08.129 route settings editor - the Reeman app's route detail page now edits index-grid visibility, width, class, and filter settings, then refreshes the route's marked field sections. Changes update the matching settings in the project-owned config.ts instead of replacing the file. See Choosing Index Grid Columns.

  • 26.08.129 multi-app agent contract - Main, Reeman, and ReeQA have separate agent commands and required loopback-only ports. Header-based impersonation can be protected with AGENT_SECRET, and each app exits instead of falling back to its normal dev port when its agent port is missing. ReeQA also requires an explicit REEQA_PORT in normal operation. See Agent Mode.

  • 26.08.129 fresh schema-module loading - CRUD generation and refresh load config.ts and schema.generated.ts in a fresh isolated module graph, so a long-running Reeman process reads settings just written during the same operation instead of Bun's cached import.

  • 26.08.127 translation bundles - Reeman can export every English namespace as one versioned bundle, validate complete or partial external translations, merge them into locales-archive/<locale>.json, and explicitly install an archived locale back into co-located runtime files. The Locales page exposes export, upload, and archived-locale import actions. See Locale Archives & Bundles.

  • 26.08.127 DATA to SQL - JSON, XLS, and XLSX imports share one inference pipeline that previews sheets and fields, normalizes columns through domain types, and writes paired MySQL and SQLite DDL plus seed data. See DATA to SQL.

  • 26.08.123 reeman Software Update page - the in-app selective-upstream-adoption page is renamed from /sync to /software-update (nav label "Software Update"). Same flow as the Reesync CLI: scan an upstream checkout, review the per-file diff, and apply only the files you choose.

  • 26.08.24 generator workflow - schema metadata is now a fresh in-memory snapshot for each generator entry point. The previous on-disk DDL cache and its manual rescan commands have been removed, so schema, CRUD, bulk, refresh, and MCP generator operations read the current database before they generate. Reeman also offers an index-grid column multi-select for single-table schema and CRUD generation, with the same explicit choice available as --grid-columns <a,b,c>. See Generators.

  • 26.08.24 safer CRUD refresh - field refresh updates marked form and index sections while preserving project-owned configuration and validation. Structural schema changes require route removal and regeneration. See Generators.

  • 26.08.24 installation reporting - first-run bootstrap and bun get:pre now report each prerequisite and setup step clearly, keep successful child output quiet, and accept --verbose when full command output is needed for diagnosis.

  • 26.07.75 display-column contract - every generated table and view now requires a string display column; an optional option_display supplies richer FK-select and autocomplete labels. Views that expand a foreign key use the exact <relationship>_display alias, so generated grids hide raw IDs and label/sort the resolved relationship consistently. Generated writes omit display columns. See Schema & Initialization and Generators.

  • 26.07.75 Reeman refinements - crud all is the all-table command, Quick Start takes reviewed admin defaults from .env, and changing database type updates both DEV_CONNECTION_STRING and TEST_CONNECTION_STRING. The bundled SQLite and MySQL schemas, plus the chefs-blog demo, now use the display-column contract.

  • Redis-backed SQL cache - opt-in caching of generated search_records queries with automatic dependency-set invalidation and a /cache admin view. Enable with CACHE_ENABLED=true + REDIS_ENABLED=true + REDIS_URL. See Caching.

  • Rate limiting - sliding-window request limiting as the first global middleware, with per-scope tiers in config/rate_limit.ts. Enable with RATE_LIMITING=true; production also requires TRUST_PROXY=cloudflare|direct. No Redis required - the counter store falls back to SQL. See Rate Limiting.

  • CSRF protection - always-on, identity-bound HMAC-signed tokens (Bun.CSRF) on state-changing requests; generated forms already include the token. Production requires CSRF_SECRET (>= 32 chars). See CSRF Protection.

  • File-first translations - co-located {locale}.json files are the source of truth, edited live through the /translations admin module or directly in the JSON. bun reeman sync-translations --translate AI-fills gaps in the files; the Prune unused / Sync missing reeman tools keep the files aligned with templates. Missing keys render as their braced key path. See Translations.

  • Pluralization - plural() selects CLDR plural forms via Intl.PluralRules from pipe-separated translation strings.

  • More AI translation providers - Ollama (local, highest priority) and Hugging Face Inference join OpenRouter. See Dynamic Translations.

  • Global (row-level) scopes - admin-defined, named WHERE filters per table via /global_scopes, folded into list queries and the cache key. See Authorization.

  • Nested CRUD (master-detail) - --parent <table> generates parent-scoped child resources with inline child lists on the parent's edit form. A parent can have multiple children. See Generators.

  • Generator improvements - ICU/CU column-visibility flags, plain-word and JSON column-comment field types, refresh-crud --mode fields to regenerate field sections only, sort options from indexed columns, fulltext search via lib/sql_dialect.ts, and the crud-ignore table tag.

  • Pagination strategies & streaming - generated list views choose offset (default) or cursor pagination via --pagination / the pagination_strategy schema export, and can stream records as Declarative Partial Updates (DPU) via render_strategy: "stream". See Pagination and Streaming.

  • Domain types - a canonical column-type vocabulary in config/domain_types/{mysql,sqlite}.ts, with a Check domain compliance reeman tool that audits a schema against it. See Schema & Initialization.

  • Agent mode - --agent runs the dev server headless, impersonating a user via the X-Agent-User-Username header or AGENT_USER_USERNAME (dev + localhost only). See Authentication.

  • CSS design system - the @theme block expands into a full token set (brand/surface/primary/semantic colours, typography, radii), and generated list views gain a right slide-in filter panel (css/filters.css). See Theming & Tokens.

  • Add/remove locale - both are one-step reeman actions that seed or strip a locale's {locale}.json files. See Adding a New Locale.

  • SQL layout & dialect isolation - schema/seed SQL moved to per-dialect folders (sql/sqlite/, sql/mysql/) with numbered files; engine-specific SQL is isolated in lib/sql_dialect.ts.

  • {#with} template directive - scopes bare variable names against a nested object, used widely in generated templates. See Displaying Data.

  • Translation-lookup tags {_ } / {- } / {@ } - read strings from props.translations by dotted key path (escaped, raw, and rendered through markdown), rendering a {last_segment} marker on a missing key instead of a crash or a silent blank. {@ } runs the resolved value through Bun.markdown.html, for a translation authored as markdown source. create_ctx() now resolves ctx.translations once per request - replacing the standalone translated_from_request() helper - and render() exposes it to templates as props.translations. Existing {= props.labels.x }-style reads become {_ labels.x }. See Translation Lookups.

  • libvips installer - bun scripts/cli.ts vips fetches a prebuilt libvips for the image-processing pipeline. See Installation.

  • Editor LSP - the Ree Templates extension bundles a Language Server Protocol server for .ree tags, helpers, and translation keys, plus hover info and go-to-definition for includes, components, and translation lookups. The LSP discovers your project structure through the new ree section in package.json.

  • Publisher signal - lib/publisher_signal/ middleware fires a fire-and-forget HTTP signal to a ReeWeb Publisher after every successful mutation (POST/PUT/PATCH/DELETE → 201/204/3xx). Set REEWEB_PUBLISHER_ENABLED=true and REEWEB_PUBLISHER_URL in .env to auto-trigger a static-site rebuild whenever content changes in the admin panel.

  • Read API column blocklist - config/api_blocklist.ts defines columns (hashed_password, invitation_code, search_text, etc.) that are stripped from JSON Read API responses regardless of table, as a safety net when api: true is set on a table with SELECT *.

  • Database structure conventions - config/db_structure.ts defines the column naming conventions that drive CRUD generation: date/datetime suffix detection (_on, _by, _at), image/file upload suffixes (_image, _file), boolean prefixes (is_, has_, can_), index/list field filters, localization eligibility rules, and grid column-width defaults.

Reporting Issues

Found something broken? Open an issue at github.com/reepolee/reepolee/issues. Include the Reepolee version (the version field in package.json), the Bun version (bun --version), and the smallest reproduction you can manage.

For security issues, email security@reepolee.com directly rather than opening a public issue.