Hello Clojure community,
I'm pleased to announce the v1.0.0 release of ShipClojure Datom — a production-ready, full-stack Clojure/ClojureScript template for building SaaS applications, AI tools, and data-rich web apps.
What is ShipClojure?
ShipClojure is a family of professional boilerplates that help you launch Clojure projects faster. Instead of spending weeks wiring up authentication, payments, deployment, and UI scaffolding, you start with everything already integrated and working.
ShipClojure comes in two stacks so you can pick the one that fits your preferences:
- ShipClojure Pragma — UIx (React) + Re-frame + PostgreSQL. Familiar patterns for teams coming from the React ecosystem, with SQL and rapid prototyping.
- ShipClojure Datom (this release) — Replicant + DataScript + Nexus + Datomic. A data-centric, immutable architecture where Datalog queries work identically on client and server.
Both stacks share the same set of production features (auth, payments, email, blog, SEO, deployment, 40+ UI themes), but differ fundamentally in how you model data, render UI, and manage state.
Why Datom?
ShipClojure Datom embraces what makes Clojure unique. Rather than wrapping React, it builds on libraries designed from the ground up for data-oriented, functional programming:
- Replicant for UI — pure functions returning hiccup data. No React, no JavaScript interop headaches. Most of your UI lives in .cljc files and is trivially testable.
- DataScript on the client — an in-memory Datalog database. Your frontend state is queryable with the same language you use on the server.
- Datomic on the server — immutable facts with time-travel queries, giving you a complete audit trail and powerful graph queries out of the box.
- Nexus for event handling — a declarative action/effect system. Actions return data vectors describing what should happen, keeping your entire event flow pure and composable.
- FCIS (Functional Core, Imperative Shell) on the backend — handlers return data vectors describing the side effects to perform (database transactions, HTTP responses, emails). The framework executes them. Your business logic stays pure and testable.
FCIS is the default, but it's not mandatory. On routes where it isn't pragmatic — syncing with external services, orchestrating many sequential impure operations — you can drop down to a plain Ring handler with no ceremony. The architecture guides you toward purity but never forces it.
The result: considerably less ClojureScript code than a React-based stack, and a codebase that is straightforward to test end-to-end with pure function assertions.
Pure Functions Everywhere — And Why That Matters for AI
This is where Datom truly separates itself from Pragma and most other web stacks.
Because Replicant components are pure functions (data in, hiccup out), every page, form, and widget is unit-testable without a browser, without React, without JSDOM. On the backend, FCIS handlers are equally pure — given a request, they return a vector of effects. No mocking, no test fixtures, no setup/teardown.
ShipClojure Datom ships with 1,000+ test assertions spanning unit and integration scenarios. Pragma has solid coverage too, but Datom's architecture makes it possible to test the entire UI layer as regular Clojure functions — something that simply isn't feasible when your components are stateful React wrappers.
This matters most when you work with AI coding assistants. The tighter the feedback loop between "generate code" and "verify it works," the more confidently you can lean on AI. With Datom, that loop is:
- AI writes a pure function (handler, UI component, action).
- You run the existing test suite — or ask the AI to write a test, which is trivial since the function has no side effects.
- Green? Ship it.
When your entire stack is built on pure functions and data transformations, AI tools can generate, refactor, and extend code with far less risk of subtle breakage.
What's Included
Everything you need to go from git clone to production:
Authentication & Security
- Email/password sign-up with JWT access + refresh tokens
- OAuth2 (Google) with streamlined onboarding
- Two-factor authentication, password reset flow
- Multi-tenant organizations with role-based access (Owner/Admin/Member)
- Token tampering detection and security event logging
Payments
- Stripe integration with checkout sessions and subscription management
- Webhook handling for payment events
Frontend
- Replicant + Tailwind CSS + DaisyUI component library
- Portfolio for interactive component development and documentation
- Client-side routing, form handling, and command/query state tracking
Backend
- Ring + Reitit with OpenAPI/Swagger docs
- CQRS pattern — declarative command/query registry with Malli schema validation
- Integrant system management, structured JSON logging with Telemere
- WebSocket support via Sente
Content & SEO
- Blog system via Powerpack
- SEO-ready static pages
- Transactional email templates via Resend
DevOps
- One-command dev startup (bb dev)
- REPL-driven development with hot reloading
- Docker-based deployment to any server via Kamal
- CI/CD pipeline setup
Datom vs. Pragma — Which One?
Choose Datom if you want complex data relationships, Datalog everywhere, immutability, minimal JavaScript dependency, and a codebase optimized for testability and AI-assisted development.
Choose Pragma if you prefer React patterns, SQL databases, and want to tap into the broader JavaScript/React ecosystem for rapid prototyping.
Both are one-time purchases with lifetime updates.
Resources
I welcome your feedback and am happy to answer questions about either stack.
Best regards,
Ovi Stoica