v3.0.0
Released: 2026-08-25
GitHub Release Notes: https://github.com/drashland/drash/releases/tag/v3.0.0
The first stable release of v3, and a complete rewrite. Drash v2 was a Deno web framework built around its own HTTP server. v3 is not an HTTP server wrapper: it is a runtime-agnostic library that runs the same application code on Deno, Node, Bun, and Cloudflare Workers.
v3 is not backwards compatible with v2. Nothing is deprecated and nothing is shimmed; the API is different because the shape of the framework is different. v2 remains on the v2.x branch.
How Long This Took
The first v3 preview shipped in October 2023, with the final beta in January 2024. Then the project went quiet for years. That matters for anyone considering a dependency: open source is unpaid work, and teams maintain it through passion—not obligation.
What the gap here means in practice:
- The published npm package lagged the source for most of that period. The docs went out of date as the runtimes continued to progress through the years.
- The v3 API itself did not drift while nobody was working on it. Most of what changed between the last beta and now is naming, documentation, and its support for runtimes.
What Drash v3 Is
Drash is not an HTTP server wrapper anymore. You build an application (using the Application class) and plug it into your runtime’s server—Deno.serve, node:http, Bun.serve, a Worker’s fetch—to handle its request-response lifecycle. For example:
import {
Application,
Resource,
} from "@drashland/drash/modules/http.polyfill.js";
class Home extends Resource {
paths = ["/"];
GET(request: Request) {
return new Response("Oh so easy");
}
}
const app = Application
.builder()
.resources(Home)
.build();
Bun.serve({
hostname: "localhost",
port: 1447,
fetch(request: Request): Promise<Response> {
return app
.handle<Response>(request)
.catch(() => {
return new Response("Sorry, but we hit an error!", {
status: 500,
statusText: "Internal Server Error",
});
});
},
});app.handle() returns a Promise and rejects on error, including a 404, so you catch it to handle your error responses.
What Changed From v2
| v2 | v3 | |
|---|---|---|
| Runtimes | Deno only | Deno, Node, Bun, Cloudflare Workers |
| Server | Bundled (Drash.Server) | None — you bring your own |
| Request / response | Drash Request and Response wrappers | Web Request and Response, or a context object you define |
| Resource input | this.request, this.response | A request (or context object for Node) |
| Middleware | Service | Middleware |
| Errors | ErrorHandler | HTTPError, handled via .catch() block where you call app.handle() |
The removals are deliberate: this.request and this.response made resources stateful for a single request. However, it prevented safe reuse across concurrent requests. Resources now initialize at build time and are reused for the app’s lifetime—eliminating per-request object creation. It’s a tradeoff among performance, semantics, and maintainability.
What Ships (Native vs. Polyfill)
There are two entry points to create an HTTP application.
modules/http.native.jsmodules/http.polyfill.js
They export the same six members. They only differ in which URLPattern implementation is used under the hood — the runtime’s global, or Drash’s bundled polyfill. See About > Concepts > Native vs. Polyfill to learn more.
Core, Standard, Modules
The entire Drash framework is made up of the following codebases:
- Core: Interfaces, types, classes
- Standard: Similar to Deno’s Standard Library and Go’s Standard Library, but smaller
- Modules: Most functionality and implementation using Standard and Core codebases
Four middleware
Four middleware, none are runtime-specific:
Documentation
Concepts, a quickstart per runtime, a full API reference, runnable examples, and agents.md for coding agents.
Supported Runtimes
| Runtime | Entry point | What a resource method receives |
|---|---|---|
| Deno 1+ | http.native.js | Web Request |
| Node 20+ | http.polyfill.js | A context object you build |
| Bun 1+ | http.polyfill.js | Web Request |
| Cloudflare Workers | http.native.js | Web Request |
Node uses the polyfill entry point because URLPattern support varies across those majors. Bun uses it because its URLPattern is not dependable.
Getting Started
- Quickstart — a complete app for your runtime
- Step-By-Step Guide — the same thing, built one piece at a time
- HTTP Application — what
Applicationassembles, and why
Coming From v2
There is no migration tool. The concepts that carry over are resources and paths; everything around them is different. Read Resources first — it is the piece of v2 that survived, and the rest of the API is built around it.