Palmyra at a glance#

Palmyra is a rapid-development framework for building database-driven web applications. Describe your data as annotated Java classes, compose the API surface you need, and wire it to ready-made React screens — the framework handles the SQL, the HTTP plumbing, the paging, the forms, and the grid refresh so your team focuses on features.


What it means for the business#

  • Faster time to market. A new entity (screen + API + database wiring) takes hours, not days. The cost per feature stays flat as the application grows.
  • Lower development cost. One developer can cover both backend and frontend. No separate teams for REST controllers, data-access layers, and UI state management.
  • Consistent quality. Pagination, sorting, validation, access control, and audit trails are built in — not reimplemented per screen.
  • Flexible UI. Swap between Mantine and MUI without rewriting business logic. The same API serves web, mobile, and third-party integrations.
  • Enterprise-ready. Multi-database support (MariaDB, MySQL, PostgreSQL, Oracle, DB2), role-based permissions, data-level security, reactive streaming for large exports, and a pluggable auth layer that works with any identity provider.

What it means for developers#

Backend developers#

Write a POJO, add a few annotations, implement one or two interfaces — and you have a working, paginated, filterable REST API. No controllers, no SQL, no DTO mappers.

@PalmyraType(type = "User", table = "users")
public class User {
  @PalmyraField(primaryKey = true) private Long id;
  @PalmyraField(search = true, sort = true) private String loginName;
  @PalmyraField private String firstName;
}

@Component
@CrudMapping(value = "/v1/user", type = User.class)
public class UserHandler implements CrudHandler {}

That gives you GET, POST, PUT, DELETE on /api/v1/user — with pagination, sorting, searching, field selection, and validation. When you need custom logic, override a lifecycle hook and keep everything else.

What the framework handles for you:

  • SQL generation from annotations — SELECT, INSERT, UPDATE, DELETE
  • Client-driven queries — the browser picks fields, filters, sort, and page size
  • Foreign-key resolution and JOIN generation from dotted-path filters
  • Parent-scoped child entities with URL-driven FK injection
  • CSV / Excel streaming exports that scale to millions of rows
  • Permission enforcement via @Permission + Spring’s standard PermissionEvaluator
  • Login, password change, and reset flows via the User Management extension
  • Data-driven ACL via the ACL Management extension

When you outgrow basic CRUD, the framework grows with you — documented advanced patterns include approval workflows, email notifications with outbox, row-level data scoping, dynamic native queries, and custom controllers secured through the same ACL.

Frontend developers#

One store factory, one endpoint string, one attribute prop per field. No axios, no per-entity fetch code, no manual paging state.

<PalmyraNewForm endPoint="/v1/user" onSaveSuccess={reload}>
  <MantineTextField attribute="loginName" label="Email" required />
  <MantineTextField attribute="firstName" label="First name" />
</PalmyraNewForm>

<PalmyraGrid columns={userColumns} endPoint="/v1/user" pageSize={[15, 30, 45]} />

That’s a working create form and a working paged grid.

What the framework handles for you:

  • HTTP transport via a single store factory — grid, form, lookup, chart, and tree stores
  • Form state, validation, dirty-check, and submit lifecycle
  • Server-side pagination, sort, search, and filter for every grid
  • Auto-generated filter panels from column definitions
  • Foreign-key pickers that query the server in real time (MantineServerLookup)
  • Read-only view widgets for detail screens
  • MUI and Mantine skins — same data layer, different look
  • Connects to any backend — implement StoreFactory for REST, GraphQL, Firebase, or legacy APIs

When you outgrow basic screens, documented recipes cover filterable dashboards, in-app discussion threads, dark/light theme switching, multilingual support, custom grid toolbars, and production error handling.


How it compares — in one sentence each#

Framework How Palmyra differs
Spring Data REST Palmyra adds client-driven field/filter negotiation, raw JDBC speed, and a matching React layer
JHipster Runtime-driven, not code-generated — add one dependency to an existing project
Hasura / PostgREST Java business logic + multi-database, delivered over REST on SpringBoot
React Admin / Refine Tighter form↔store lifecycle; also works with non-Palmyra backends via custom StoreFactory
Rails / Django / Laravel API-first Java/React stack instead of a monolith with server-rendered HTML

Full comparison with decision heuristics → Comparison.


Is Palmyra for you?#

Good fit:

  • Admin panels, back-office tools, internal line-of-business apps — mostly CRUD with occasional custom flows
  • Teams that own a relational database and want to stay close to the schema
  • Java + SpringBoot on the server, React on the client — one contract, not three

Not the right fit:

  • Heavily GraphQL-shaped public APIs → Hasura / Spring GraphQL
  • Document-style NoSQL apps → Mongoose / Spring Data MongoDB
  • Zero-config code generation with opinionated scaffolding → JHipster

Where to start#

If you want to… Go here
Understand the concepts in plain language Concepts
Build your first app end-to-end My First Application
See advanced recipes (workflows, dashboards, email, i18n) Tutorial — Advanced
Evaluate Palmyra against alternatives Comparison
See which business problems it solves Use Cases
Read the HTTP contract for mobile / third-party integration API Format
Browse per-component API reference Reference