This content originally appeared on DEV Community and was authored by Fernando Correa de Oliveira
Introduction
When I start something new in Raku with Cro, I almost always begin with a mental sketch: two or three routes, a response shape, maybe a typed segment. In the Perl world I leaned heavily on Mojolicious::Lite
for that prototyping phase. In Cro—powerful and modular as it is—I missed an immediate “lite mode”: no manual wiring of server, pipeline, and router just to test a thought. Out of that friction came Crolite: a thin layer that re‑exports Cro's routing keywords and adds a multi MAIN
with quick exploration commands.
What Crolite Is
- Goal: Make minimal HTTP prototypes trivial while ideas mature.
- Approach: Reuse Cro's router directly; no new DSL.
-
Deliverable: A collected
RouteSet
+ a tiny embedded CLI. - Philosophy: “Start now; graduate later to a full Cro app.”
Installation
From a local checkout (inside the project directory):
zef install .
Once published:
zef install Crolite
First Example
File example.raku
:
use Crolite;
get -> $any {
content 'text/plain', "Hello: $any";
}
delete -> 'thing', Int $id {
content 'application/json', %( :$id );
}
List derived routes:
raku example.raku routes
Run a development server:
raku example.raku daemon --host=127.0.0.1 --port=3000
Test a route without a persistent daemon (ephemeral in‑memory request):
raku example.raku GET /thing/42
Suggested Workflow
- Sketch routes and response formats.
- Run
raku app.raku routes
to confirm patterns. - Fire single requests:
raku app.raku GET /foo/123
. - Iterate until it stabilizes.
- Promote to a full Cro project if you need richer middleware, structured logging, TLS, etc.
CLI Options
Command | Purpose |
---|---|
routes |
Print summary of registered endpoints |
daemon [--host=0.0.0.0] [--port=10000] |
Start simple Cro server |
GET <path> |
Single in‑memory GET |
POST <path> |
Single POST (no custom body) |
PUT <path> |
Single PUT |
DELETE <path> |
Single DELETE |
http <path> --method=<VERB> |
Generic form for any method |
Stop the daemon with Ctrl+C
(SIGINT is trapped for graceful shutdown).
Dynamic Segments & Typing
use Crolite;
get -> 'greet', Str $name {
content 'text/plain', "Hi $name!";
}
post -> 'sum', Int $a, Int $b {
content 'application/json', %( total => $a + $b );
}
Test:
raku app.raku GET /greet/Ana
raku app.raku POST /sum/2/5
Returning JSON
Just produce a Hash
or Map
:
get -> 'status' {
content 'application/json', %( service => 'ok', ts => DateTime.now );
}
Hooks (Before / After)
If you manually add before
or after
handlers to the underlying RouteSet
, Crolite includes them when composing the application for daemon
:
use Crolite;
$*CRO-ROUTE-SET.before: {
# Simple logging / auth stub
proceed;
}
get -> 'ping' { content 'text/plain', 'pong' }
More Complete Example
use Crolite;
get -> 'health' {
content 'application/json', %( ok => True );
}
put -> 'echo', Str $msg {
content 'text/plain', $msg.uc;
}
post -> 'calc', Int $x, Int $y {
content 'application/json', %( sum => $x + $y, prod => $x * $y );
}
delete -> 'soft', Int $id {
content 'application/json', %( deleted => $id, soft => True );
}
Quick ping:
raku app.raku GET /health
Server:
raku app.raku daemon --port=4000
Ergonomics While Prototyping
- Rapid changes: Save & re‑run; no auto‑reloader (yet).
-
Inspection:
routes
surfaces path typos immediately. -
Atomic requests: Avoids opening another terminal for
curl
just to see a body.
Current Limitations
- No structured logging out of the box.
- No built‑in TLS / websockets / streaming presets.
- No hot reload.
- Experimental API (may shift).
When to Migrate to a Full Cro App
- You need chained middleware (auth, tracing, rate limiting).
- You require richer body parsing / serialization customization.
- You integrate multiple services or supervised components.
- You need observability (metrics, distributed tracing, advanced logs).
Possible Future Roadmap
- Optional reload in
daemon
mode. - Alternate tabular output for
routes
. - Lightweight latency / metrics helper.
- Test skeleton generator for promotion phase.
Quick Testing Tips
- Use the embedded CLI to validate the contract before formal tests.
- When formalizing, reuse
Cro::HTTP::Test
(mirrors what the CLI verbs do).
Wrapping Up
Crolite does not compete with the full flexibility of a structured Cro project; it lowers the time to first useful response when exploring HTTP ideas in Raku. If you also miss the lightness of Mojolicious::Lite
, try making the first step of each spike just:
use Crolite;
Then, once the shape hardens, graduate to something more robust.
Suggestions, issues, and PRs welcome.
This content originally appeared on DEV Community and was authored by Fernando Correa de Oliveira

Fernando Correa de Oliveira | Sciencx (2025-09-28T00:28:31+00:00) Crolite: filling the “Mojolicious::Lite” gap in the Cro ecosystem. Retrieved from https://www.scien.cx/2025/09/28/crolite-filling-the-mojoliciouslite-gap-in-the-cro-ecosystem/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.