How Palmyra compares#

An honest side-by-side with the frameworks teams typically evaluate alongside Palmyra. Every tool has a sweet spot; the goal here is to help you decide, not to sell.

Palmyra’s frontend works with any backend. Implement a custom StoreFactory and the same grids, forms, and lookups talk to REST, GraphQL, Firebase, or any legacy API — no component changes needed. See Connecting to a custom backend.


Backend comparisons#

vs Spring Data REST#

Spring Data REST auto-publishes JPA repositories as REST endpoints — conceptually the closest alternative.

Palmyra advantage Spring Data REST advantage
Query flexibility Client picks fields, filters, sort, and pagination via query params; server compiles the SQL HAL/JSON-API-standard hypermedia out of the box
Performance Raw JDBC under the hood — no Hibernate session, no lazy-loading surprises; sub-50 ms typical Leverages full JPA/Hibernate ecosystem (caching, dirty-check, cascades)
Lifecycle hooks Fine-grained: preCreate, onUpdate, applyQueryFilter, onQueryResult — per handler Event-based (@HandleBeforeSave, @HandleAfterCreate) — broader but less granular
Export CsvHandler / ExcelHandler stream reactively out of the box No built-in export — add a custom controller
Frontend Ships a matching React component library (Mantine + MUI) Frontend-agnostic — bring your own
Community Smaller; documentation is this site Massive Spring ecosystem; extensive third-party tutorials
Schema flexibility @PalmyraMappingConfig lets you declare FK/UK in code when DB doesn’t have them Relies on JPA metadata — if it’s not in the entity, it doesn’t exist

Pick Palmyra when you want client-driven queries + raw JDBC speed + an integrated React layer. Pick Spring Data REST when you need hypermedia, Hibernate’s full ORM surface, or the Spring ecosystem’s breadth.

vs JHipster#

JHipster generates a full-stack app (Spring Boot + Angular/React/Vue) from a domain model DSL.

Palmyra advantage JHipster advantage
Philosophy Runtime-driven — no code generation, no regeneration drift One-command scaffold with CI/CD, Docker, monitoring, microservices
Incremental adoption Add one dependency to an existing SpringBoot project Designed to own the whole project from day one
Entity changes Edit the POJO, restart — done Re-run the generator, resolve merge conflicts
Frontend flexibility Swap Mantine ↔ MUI; compose your own pages Generated screens are opinionated — customising means editing generated code
Learning curve Learn annotations + handler interfaces Learn JDL (domain language) + the generated project structure
Production scaffolding You bring your own CI/CD, Docker, monitoring Ships with Prometheus, ELK, Docker Compose, Kubernetes configs
Microservices Not in scope — Palmyra is a library, not an architecture First-class microservice/gateway support

Pick Palmyra when you have an existing SpringBoot project or want to stay closer to plain Java code. Pick JHipster when you’re greenfield, want an opinionated full-stack generator, and need microservice scaffolding.

vs Hasura / PostgREST#

Auto-generated APIs from a PostgreSQL schema — no Java, no SpringBoot.

Palmyra advantage Hasura / PostgREST advantage
Language / stack Java / SpringBoot — fits teams that already run JVM services Zero backend code; configure via dashboard or YAML
Business logic Handler lifecycle hooks (Java) — arbitrary complexity Hasura Actions / PostgREST functions — limited to SQL or a sidecar service
Multi-database MariaDB, MySQL, PostgreSQL, Oracle, DB2 PostgreSQL only (Hasura adds some others with Enterprise)
Frontend Ships matched React components Frontend-agnostic (GraphQL clients everywhere)
Client query shape REST with query params GraphQL — richer query language, subscriptions
Deployment Standard Spring Boot .jar — runs anywhere Java runs Separate containerised service; Hasura Cloud for managed
Joins Declared via annotations or DB metadata; dotted-path filters auto-join Auto-discovered from FK constraints; GraphQL nested queries

Pick Palmyra when you need Java business logic, multiple DB vendors, or a matched frontend layer. Pick Hasura / PostgREST when you want zero backend code, PostgreSQL is your only DB, and GraphQL is the API shape you need.

vs plain Spring @RestController#

No framework beyond Spring Boot itself.

Palmyra advantage Plain Spring advantage
Boilerplate per entity 1 POJO + 1 handler Controller + service + repository + DTO + mapper
SQL generation Automatic from annotations You write it (JPQL, native SQL, or Criteria API)
Pagination / sort / filter Built in — _limit, _offset, _orderBy, per-field filters Hand-rolled or Spring Data Pageable (no field-projection negotiation)
Export CsvHandler / ExcelHandler — one interface Custom streaming controller
Total control Lifecycle hooks give you extension points; framework owns the plumbing You own everything — no framework opinions to work around
Learning curve Framework vocabulary (annotations, handlers, stores) Standard Spring — no extra concepts
Debugging One more layer between your code and the database Your code IS the layer — stack traces are shorter

Pick Palmyra when the entity count is high and CRUD is the dominant pattern. Pick plain Spring when every endpoint is bespoke, or you need full control of the SQL and response shape.

vs JOOQ / MyBatis#

Type-safe SQL builders or SQL-template engines — backend only, no framework.

Palmyra advantage JOOQ / MyBatis advantage
Scope Full vertical: model → handler → URL → React grid SQL layer only — you still write controllers, DTOs, and the frontend
Speed of delivery One POJO + one handler = working endpoint Write exactly the SQL you want — maximum control
Client-driven queries Built in You build the filter/sort/page logic yourself
Complex SQL NativeQueryHandler for hand-written queries when annotations aren’t enough Every query is hand-written — JOOQ adds type safety, MyBatis adds XML mapping
Compile-time safety Runtime annotation processing JOOQ: compile-time type-checked SQL; MyBatis: IDE-assisted XML

Pick Palmyra when you want the full stack, not just the SQL layer. Pick JOOQ / MyBatis when your SQL is complex enough that a framework-generated query won’t cut it, and you’re happy to build the REST + frontend layers yourself.


Frontend comparisons#

vs React Admin / Refine#

Data-provider + resource-component frameworks for admin UIs.

Palmyra advantage React Admin / Refine advantage
Backend match PalmyraStoreFactory speaks the Palmyra API natively — zero adapter code; custom StoreFactory implementations connect to any backend Generic data providers for REST, GraphQL, Supabase, Hasura, Appwrite, … — large catalogue of ready-made adapters
Form ↔ store lifecycle PalmyraNewForm / PalmyraEditForm handle fetch + save + validation in one component Richer ecosystem of pre-built “resource” pages and admin chrome
UI library Mantine or MUI — real component-library code, not wrapped React Admin: MUI only; Refine: headless + optional Ant/MUI/Mantine
Plugin ecosystem Smaller — FilterForm, SelectablePagination, SummaryGrid Larger — auth providers, i18n, audit log, realtime, access control built in
Community Emerging React Admin: 24 k+ GitHub stars; Refine: 29 k+
Backend flexibility Interface-driven: implement StoreFactory to talk to any backend (REST, GraphQL, Firebase, SOAP) — guide Provider-driven: pick a ready-made data provider or write a custom one

Pick Palmyra’s frontend when you want tight form/grid/store integration and are comfortable implementing a StoreFactory for your backend (zero effort if the backend is Palmyra). Pick React Admin / Refine when you need a ready-made data-provider catalogue for diverse backends, a broader plugin ecosystem, or community size matters for hiring.

vs React Hook Form + axios + a grid library#

The “assemble it yourself” approach.

Palmyra advantage DIY advantage
Integration One factory, one form component, one grid component — wired together; works against any backend via custom StoreFactory Mix any grid (AG-Grid, TanStack, MUI DataGrid) with any form (RHF, Formik) and any HTTP client
Per-entity boilerplate 1 endpoint string + attribute props — no per-entity fetch/state code Full control — but you write it for every entity
Grid features Paging, sort, search, filter-panel, export — built in Choose exactly the features you need — nothing forced
Escape hatch useServerQuery and generateColumns give you TanStack Table underneath You already have TanStack Table — no abstraction to escape from
Bundle size Palmyra wire + rt-forms + skin Only the pieces you pick — potentially lighter
Learning curve Framework vocabulary (stores, forms, grids, templates) Standard React — no extra concepts

Pick Palmyra when entity count is high and you want to stop writing the same fetch/grid/form wiring for each one. Pick DIY when you have a handful of bespoke screens, bundle size is critical, or you need a grid library Palmyra doesn’t wrap.

vs Retool / Appsmith (low-code)#

Drag-and-drop internal-tool builders.

Palmyra advantage Low-code advantage
Code ownership You own every file — version control, code review, CI/CD Visual builder — non-developers can build screens
Customisation Arbitrary React — any layout, any logic, any library Constrained to the builder’s widget set and scripting model
Deployment Standard web app — deploy anywhere Hosted SaaS or self-hosted container
Cost at scale Open source — no per-seat licensing Per-seat pricing can climb fast with large teams
Speed for simple screens Write code (fast, but still code) Drag, drop, connect — faster for simple CRUD with no custom logic
Complex business logic Java handler hooks — full language JavaScript snippets in a sandbox — limited

Pick Palmyra when the team has developers, the logic is non-trivial, and you need full code ownership. Pick low-code when the screens are simple, the team includes non-developers, and speed to first screen matters more than long-term flexibility.


Full-stack framework comparisons#

vs Ruby on Rails / Django / Laravel#

Server-rendered full-stack frameworks with mature ecosystems.

Palmyra advantage Rails / Django / Laravel advantage
Architecture API-first (JSON REST) + separate React SPA — modern client/server split Monolith with server-rendered HTML — simpler deployment, no CORS, no SPA build step
Frontend richness Full React SPA with Mantine / MUI — richer interactivity Turbo / HTMX / Livewire add interactivity without a full SPA
Performance Raw JDBC, JVM — strong throughput under load Interpreted (Ruby/Python/PHP) — typically slower per-request, but fine for most workloads
Language Java (backend) + TypeScript (frontend) — two languages One language (Ruby / Python / PHP) for both — lower cognitive overhead
ORM Optional — Palmyra generates SQL from annotations; JPA available alongside ActiveRecord / Django ORM / Eloquent — deeply integrated, heavily documented
Ecosystem maturity Newer; smaller community Decades of libraries, gems, packages, tutorials, Stack Overflow answers
Admin scaffolding Handler + POJO = endpoint; frontend is explicit code rails generate scaffold / Django Admin / Nova — instant admin with less code

Pick Palmyra when you want a Java/React stack, API-first architecture, and client-driven queries. Pick Rails / Django / Laravel when you prefer a monolith, server-rendered HTML, one-language simplicity, or need the depth of a 15+ year ecosystem.


Summary — Palmyra’s sweet spot#

Palmyra is strongest when:

  • The problem is entity-heavy CRUD with relational data — many tables, many screens, same patterns.
  • The team wants Java on the server and React on the client — and wants them to share a contract, not a build system.
  • Client-driven query flexibility matters — the browser decides what it needs, the server compiles it.
  • Speed of delivery per entity matters more than maximum control per endpoint.
  • The database schema is the source of truth — not an ORM, not a GraphQL schema, not a code generator.

The frontend is also strong when:

  • You have a non-Palmyra backend but want Palmyra’s form/grid/store integration — implement a custom StoreFactory and every React component works unchanged.
  • You’re migrating incrementally — start with Palmyra’s React layer against your existing API, then adopt the backend SDK entity by entity.

The advanced pattern library is also a differentiator — production concerns that require bespoke code in most frameworks are documented recipes in Palmyra: approval workflows, child-entity handlers with nested URLs, email outbox, row-level security, dynamic dashboard queries, custom controllers with ACL, filterable dashboards, i18n, discussion threads, and production error handling.

It’s weakest when the API is heavily GraphQL-shaped, the database is NoSQL, the team doesn’t write code (low-code is better), or every endpoint is bespoke enough that a framework adds more concepts than it removes.


Where to start#