Fresh is a simple web framework based on the latest
web standards that we built and use quite heavily here at Deno. We’ve teased the
next version for quite some time now, but haven’t yet cut a release. Rest
assured we haven’t forgotten about it. In fact,
a pre-release version of Fresh 2 is
being used in production here at Deno — on our main website as well as on
Deno Deploy.
Whenever we post an update regarding Deno on any of our social channels, many of
you ask: What about Fresh 2? After all, we have announced plans to start working
on Fresh 2 a long while ago and
it isn’t out yet a year later. So this blog post is an update on where we’re at.
- Why Fresh 2?
- Why the delay?
- Where is Fresh 2 now?
- What does Fresh 2 bring?
- How to get Fresh 2 alpha
- Coming soon
Why Fresh 2?
The first version of Fresh was originally created as a simple way to build
websites leveraging the latest web technologies available in Deno. It quickly
rose in popularity among Deno users, so much so that
Fresh 1.0 became one of the
top starred GitHub frontend projects that year.
Since then, we pushed many improvements, like becoming faster, new features like
Partials and a lot of polish.
However, as the needs of Fresh projects grew, we encountered new challenges.
Projects with larger islands, more routes, more assets, as well as a desire to
extend aspects of Fresh were pushing the limits of the Fresh 1 code base. Adding
new features became harder and harder and it was obvious that we needed a better
foundation to make Fresh advance.
This is a normal part of the evolution of a software project; you try an
approach, see what works and what doesn’t, and iterate from there. We got to
work and, with all the learnings from Fresh, built a new architecture for
Fresh 2.
Why the delay?
Building a truly next-generation framework sometimes means reinforcing the
underlying foundations first. To make Fresh 2.0 faster, more extensible, and
more delightful to use than ever before, we dedicated significant effort to
enhancing the core Deno platform and our JavaScript registry, JSR. While this
foundational work was time-intensive, it was crucial for the advanced features
and stability we’re now bringing to Fresh 2.
Things were going very well during the initial development of Fresh 2.
Nevertheless, looking at the issue tracker and questions asked in our Discord
channel, made it clear that the majority of issues couldn’t be fixed in Fresh
itself. They needed to be fixed in Deno as they were caused by underlying
technologies such as http:
specifiers and Node compatibility. In order to
deliver on the ambitious goals we had for Fresh 2, we had to take a step back
and ensure these foundational pieces were robust.
Ecosystem compatibility
We always wanted to support third-party npm packages directly and seamlessly in
Fresh. To truly realize this, it became vital to first enhance core aspects of
Deno itself. Focus temporarily shifted to contribute directly to
the Deno 2 release, building the critical groundwork for
Fresh 2 to thrive, particularly around Node and npm compatibility. This
groundwork directly enables a smoother experience with a wider range of packages
in Fresh 2, and we were able to resolve many related compatibility issues as a
result. However, this work remains ongoing.
Simplifying via JSR and Deno Deploy
One issue that users encountered frequently was with import maps or duplicate
dependencies in their code. This was another issue better served by addressing
underlying technologies. While we migrated Fresh to
JSR, we focuesd on JSR to improve its usability, which in turn
simplifies dependency management for Fresh projects.
After that, attention was turned to work on the next iteration of Deno Deploy,
which will include a build step (more details about this in a future blog post).
We used Fresh and Fresh 2 as a test case with the next version of Deno Deploy,
aiming to build the best possible deployment experience. Whilst these projects
took the bulk of my engineering efforts, they also lay the foundation for a
better Fresh.
Where is Fresh 2 now?
Whilst work on these foundational projects was going full steam ahead, we made
sure to switch our own projects to the alpha version of Fresh 2. This gave us
ample time to battle test it more.
Fresh 2 is already powering deno.com and Deno Deploy in production, but we’re
still putting the final touches on the plugin system, bundler integration, and
overall developer experience. Our target for the Fresh 2.0 stable release is
late Q3 2025 (likely September). This timeline allows us to diligently
incorporate community feedback from the alpha and ensure the high level of
polish we’re committed to. We’ll provide more precise date estimates as we get
closer and hit our internal milestones.
What does Fresh 2 bring?
Fresh 2 in makes the framework much more extensible, faster and easier to work
with. The core API has been simplified to resemble similar APIs as you might
know already from other frameworks like express
or koa
.
This next major version will introduce Express/Hono-like APIs, true async
components, and a new plugin system for creating and sharing Fresh middleware.
const app = new App(); app.use((ctx) => { console.log(`Here is a cool request: ${ctx.url}`); return ctx.next(); }); app.get((ctx) => { return new Response("it works!"); }); await app.listen();
Adding custom middlewares, routes or other things is much easier with this. The
signature of middlewares and handlers are the exact same, so you don’t need
different types for them anymore either.
const foo = (req: Request, ctx: FreshContext) => new Response("hello"); const foo = (ctx: FreshContext) => new Response("hello");
Fresh 2 also ships with support for the precompile
JSX transform in Deno out
of the box. This significantly speeds up rendering. And much more…
How to get Fresh 2 alpha
Fresh 2.0 is currently available as an alpha release. While this means there
might still be some evolving APIs or occasional rough edges as we iterate based
on feedback, we’re incredibly excited about its current capabilities. In fact,
we’re already battle-testing it in production on deno.com and Deno Deploy! We
encourage you to try it for new projects or in development environments, and
your feedback during this phase is invaluable as we progress towards stability.
To get the best experience with Fresh 2.0 alpha, we also recommend using it with
the newly released Deno 2.3! This version includes features like
improved deno compile
and
local npm packages which further streamline
your Fresh development workflow. Learn more about Deno 2.3 here.
From scratch
You can run Fresh’s scaffolding script in your terminal with this command:
$ deno run -Ar jsr:@fresh/[email protected] 🍋 Fresh: The next-gen web framework. Project Name: fresh-project Set up Tailwind CSS for styling? [y/N] y Do you use VS Code? [y/N] y Project initialized! Enter your project directory using cd fresh-project. Run deno task start to start the project. CTRL-C to stop. Stuck? Join our Discord https://discord.gg/deno
Going into your newly created Fresh project then running deno task dev
and
pointing your browser to localhost:8000
:
Upgrading an existing Fresh project
If you already have an existing Fresh project, you can upgrade to Fresh
2.0.0-alpha.30 from your command line:
$ deno run -Ar jsr:@fresh/[email protected]
This will apply most API changes made in Fresh 2 automatically, like updating
$fresh/server.ts
imports to fresh
.
For more details on migrating an existing Fresh project to Fresh 2,
check out our migration guide.
Coming soon
Fresh 2 has been a joy to work with at Deno, and we’re excited to bring this
much simpler and extensible version of Fresh to you as we approach the stable
release later this year. Your feedback on the alpha versions is crucial, so
please give it a try and let us know what you think!
🚨️ Deno 2.3 released! 🚨️
- Improved
deno compile
- Local npm packages
- OTel event recording & tracing in distributed services and more