Skip to main content
Deno 2.3 is here with improved deno compile, local npm packages, and more 🚀
Learn more
A giant lemon

An Update on Fresh

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?

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();

// Custom middlewares
app.use((ctx) => {
  console.log(`Here is a cool request: ${ctx.url}`);
  return ctx.next();
});

// Also can be branched on by HTTP method
app.get((ctx) => {
  return new Response("it works!");
});

// Finally, start the app
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.

// Fresh 1.x middleware
const foo = (req: Request, ctx: FreshContext) => new Response("hello");

// Fresh 2.0 middleware
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/init@2.0.0-alpha.33
 🍋 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:

New Fresh project

Upgrading an existing Fresh project

If you already have an existing Fresh project, you can upgrade to Fresh 2.0.0-alpha.33 from your command line:

$ deno run -Ar jsr:@fresh/update@2.0.0-alpha.33

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! 🚨️