22 independent libraries. Enforced FC/IS architecture. One coherent stack, zero lock-in.
Stop stitching together libraries. Every component follows the same patterns, tests the same way, and swaps via configuration.
Every Boundary module follows Functional Core / Imperative Shell. The directory structure makes clean architecture the default — not a convention that erodes over time.
shell/ports.cljcore/Enforced by directory layout + clj-kondo rules · Every library follows the same structure
Each library is a standard deps.edn dependency, independently publishable to Clojars.
# Natural language module generation $ bb scaffold ai "order module with customer, total, status" ✓ Schema defined schema.clj ✓ Validation rules core/validation.clj ✓ Persistence layer shell/persistence.clj ✓ HTTP routes shell/routes.clj ✓ Service layer shell/service.clj ✓ Tests generated test/core_test.clj Generated 6 files in libs/order/ All tests passing: 12/12
(ns boundary.order.schema (:require [malli.core :as m])) (def Order [:map [:id :uuid] [:customer-id :uuid] [:total [:and :decimal [:> 0]]] [:status [:enum :pending :paid :shipped :delivered]] [:created-at :instant]])
(defworkflow order-workflow {:initial-state :pending :states #{:pending :paid :shipped :delivered :cancelled} :transitions [{:from :pending :to :paid :required-permissions [:finance]} {:from :paid :to :shipped :guard :payment-confirmed} {:from :shipped :to :delivered}]}) ; Pure core logic — no I/O, no mocks needed
The entire state machine lives in core/ — no I/O, no side effects. Test every transition without a database or mock.
Every state change is recorded with who, when, and from/to state. Query with plain SQL.
Role-based guards and custom guard functions. The workflow rejects invalid transitions at the transition layer.
;;; Development — zero setup, zero config {:boundary/db-context {:adapter :sqlite :db "dev.db"} :boundary/cache {:adapter :in-memory} :boundary/observability {:log-adapter :stdout :err-adapter :no-op}} ;;; Production — one key change each. Zero code changes. {:boundary/db-context {:adapter :postgresql :host #env DB_HOST :pool-size 10} :boundary/cache {:adapter :redis :uri #env REDIS_URL} :boundary/observability {:log-adapter :datadog :err-adapter :sentry :dsn #env SENTRY_DSN}}
;;; Cross-cutting concerns declared alongside the route. {:path "/api/admin/orders" :methods {:post {:handler 'handlers/create-order :interceptors ['auth/require-admin 'audit/log-action 'rate-limit/admin 'metrics/record-latency]}}} ;;; Service layer — one macro call, all telemetry automatic (defn create-order [this order-data] (service/execute :create-order {:order order-data} (fn [{:keys [params]}] (order-core/prepare (:order params))))) ; Automatically instruments: structured logs, metrics, ; Sentry breadcrumbs, PII redaction. No telemetry code needed.
Kit, Phoenix, Django, and Rails all require you to assemble and wire the pieces yourself. Boundary ships FC/IS enforcement, auto-admin UI, multi-tenancy, state machine workflows, full-text search, report generation, PII redaction, and framework-aware AI tooling — built in, consistent, following the same patterns across all 22 libraries.
Numbers based on comparing Boundary to assembling a custom Clojure stack from scratch.
The ROI compounds. Small teams ship faster. Growing companies scale without chaos. Enterprises govern without mandates.
Follow development on GitHub, chat on Clojurians Slack, and catch tutorials on YouTube.