RIFE2 is a full-stack framework for building web applications in plain, type-safe Java.
Routing, templates, forms, persistence and tests are all ordinary Java code, with no XML, YAML or reflection magic. The compiler and your IDE understand your whole application, giving you completion, refactoring, navigation and type checking everywhere.
See RIFE2 in action
Each tab is a small, focused example. Try it live runs an interactive playground, served by this site, that exercises it, and every playground links to its own source.
A fully functional web application in a dozen lines
Run It!
./bld compile run # using the bld build tool
./gradlew compile run # using the Gradle build tool
View It!
http://localhost:8080/hello
Try it live
Served live by rife2.com, which is itself a RIFE2 app. View the source: DemoRouter.java and its template: hello.html
Routes are fields, so links and URLs are type-safe and survive refactoring
Try it live
The link's URL is generated from the route. Click it and Hello World appears. View the source: DemoRouter.java and its template: link.html
One template, one route: GET shows the form, POST shows the result
Try it live
One element serves both the GET that shows the form and the POST that shows the result. View the source: FormDemo.java and its template: form.html
Validation rules live on the bean, and RIFE2 checks every field server-side
Try it live
Submit the form and each field that breaks its constraints gets a precise error. Try an empty name, a bad email, or an age like 5. The rules can also live in a separate metadata class, keeping the bean a plain POJO. View the source: ValidationDemo.java and its template: validation.html
A CSRF token guards every state-changing request, so other sites can't forge them
Try it live
The real verification runs out of container. A legitimate submit is accepted, a forged cross-site request gets 403. View the source: CsrfDemo.java and its template: csrf.html
Beans and records convert to and from JSON, without annotations or dependencies
Try it live
Change the name and the live JSON API answers. The record's fields become the keys, with no annotations. This calls the running endpoint and shows exactly what it returns. View the source: JsonDemo.java
Templates are plain files with no embedded logic or expressions (HTML here, also XML, text, JSON and more): named blocks are the pieces, and Java assembles them. Open the live demo and the branch that runs for the current state lights up here.
Try it live
The same logic-less template renders both pages, and the highlighted lines above are the Java branch that just ran. Flip the state and only the Java's choice of block changes. View the source: TemplatesDemo.java and its template: templates.html
One element serves a browser the whole page and htmx just the changed fragment, with no client-side rendering code
Try it live
Type to filter: each keystroke fetches only the updated list, returned with printHtmxFragment from a template block rather than as a whole page.
View the source: HtmxDemo.java
and its template: htmx.html
A local variable preserved across requests, resuming exactly where it paused
Try it live
Every visitor gets their own counter. Open in its own tab and it counts independently. View the source: CounterDemo.java and its template: counter.html
Server-sent events with broadcasters that push from anywhere to every connected client or a filtered subset
Try it live
The clock is pushed once per second, and every tap is broadcast to all watchers. Open in its own tab, tap in one, and watch both jump. View the source: DemoRouter.java and its template: sse.html
Coordinate concurrent tasks as straight-line code that pauses on events, without managing threads or locks
Try it live
A warehouse, a courier and a notifier hand a parcel down the line, each written top to bottom and suspended mid-method by pauseForEvent. Place an order and it runs its own workflow to completion in one request.
View the source: WorkflowDemo.java
and its template: workflow.html
Versioned schema evolution with declarative, reversible migrations
Try it live
Step up and back to watch the real schema change. Each step runs against its own throwaway database. View the source: MigrationsDemo.java and its template: migrations.html
SQL queries built through a Java API, rendered in each database's own dialect
Try it live
Pick a database and only the generated SQL changes. One type-safe query, tailored to each dialect, and RIFE2 even rejects a clause a database can't run. View the source: QueriesDemo.java and its template: queries.html
The manager derives the table from a plain bean, then saves and restores rows with no SQL
Try it live
Add a book and the manager saves it and reads it straight back. Each request runs against its own private in-memory database that is discarded afterward, so nothing accumulates between requests. View the source: GqmDemo.java and its template: gqm.html
Out-of-container tests drive forms and links like a browser, with no running server
Try it live
The test finds the form in the HTML, fills it, and submits it, all in-process. Change the expected value to make it fail. View the source: TestDemo.java and its template: test.html
Just the beginning
While the examples above each run live on this page, they show only a small part of what RIFE2 offers, and its layers are built to work together.
These are some of the features:
Full Stack in 2.5MB No Dependencies Web Continuations Bidirectional Templates Server-Sent Events Pure Java Build System
Web
- Engine with Continuations
- Clean-URL Path Mapping
- Out-of-container Testing
- Form Building
- Dynamic Validation
- Server-Sent Events with Replay
- htmx Integration
- Customizable Authentication
- CSRF Protection
Runtime & Deployment
- Embedded Jetty or Tomcat
- Virtual Threads by Default
- Jakarta EE 10/11 War Deployment
- GraalVM Native Images with Continuations
- Explicit Java Module
- Hierarchical Configuration
- Persisted Scheduler
- Dependency Injection
- Workflow Engine with Continuations
Data
- Database Query Builders
- Generic Query Manager
- Declarative Migrations
- Bean-centric Metadata and Constraints
- JSON with Bean Conversion
- Content Management
Templates & Content
- Bidirectional Logic-less Templates
- Localization
- RSS, Atom and JSON Feeds
- WebJars
- Resource Abstraction
Tooling
- Pure Java Build System (bld)
- IntelliJ IDEA Plugin
- Gradle Plugin
Visit the project Read the documentation Learn more about bld
Virtual threads by default
On Java 21 and later, RIFE2's embedded server runs every request on its own virtual thread, with no configuration. You write ordinary blocking code: a database query, an HTTP call or a file read, parks only that thread instead of tying up a pooled request thread. There is no reactive API and no async plumbing to learn, and blocking code can scale to many concurrent I/O-bound requests because virtual threads are cheap to create and park. When deployed to an external servlet container, RIFE2 leaves request threading to the container. Either way, it fits the rest of RIFE2, which offers the same sequential model: continuations pause and resume a flow across requests, and the workflow engine coordinates concurrent tasks as straight-line code that waits on events.
Built for AI-assisted development
RIFE2's design suits AI coding assistants. Everything is plain, type-safe Java: no XML or YAML, no required annotations, and no reflection magic, so the compiler and the agent both read the application's structure straight from the source. Nothing is hidden: routes are fields, elements are classes, and templates are files, all discoverable by reading the code. The framework is a single 2.5MB jar with zero dependencies, built by bld in plain Java, so there is less machinery to reverse engineer. Out-of-container tests exercise the whole request cycle in memory for a fast compile-and-test loop, and an llms.txt at the site root gives agents an index of the framework's documentation.
Find out more
RIFE2's source code, community and issues can be found on GitHub:
https://github.com/rife2/rife2
About RIFE2
RIFE2 builds on the foundations of the original RIFE framework that was popular from 2002 to 2010. It preserves most of the original features and adds new ones, for a fraction of the footprint and with even greater developer productivity. RIFE2 is created and maintained by Geert Bevin, veteran Java coder and one of the first Java Champions.