惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Apple Machine Learning Research
Apple Machine Learning Research
S
Schneier on Security
P
Proofpoint News Feed
The Cloudflare Blog
S
SegmentFault 最新的问题
WordPress大学
WordPress大学
Hugging Face - Blog
Hugging Face - Blog
雷峰网
雷峰网
博客园 - 【当耐特】
博客园 - 叶小钗
大猫的无限游戏
大猫的无限游戏
F
Fortinet All Blogs
宝玉的分享
宝玉的分享
博客园 - 聂微东
Engineering at Meta
Engineering at Meta
G
Google Developers Blog
Know Your Adversary
Know Your Adversary
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
S
Securelist
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
C
CXSECURITY Database RSS Feed - CXSecurity.com
G
GRAHAM CLULEY
T
Threatpost
T
Threat Research - Cisco Blogs
酷 壳 – CoolShell
酷 壳 – CoolShell
C
Cisco Blogs
Cisco Talos Blog
Cisco Talos Blog
Latest news
Latest news
C
Cybersecurity and Infrastructure Security Agency CISA
L
LINUX DO - 热门话题
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
SecWiki News
SecWiki News
L
LangChain Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
The Last Watchdog
The Last Watchdog
阮一峰的网络日志
阮一峰的网络日志
Security Latest
Security Latest
P
Palo Alto Networks Blog
L
LINUX DO - 最新话题
博客园 - 司徒正美
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
P
Privacy International News Feed
N
News and Events Feed by Topic
Spread Privacy
Spread Privacy
T
Tenable Blog
有赞技术团队
有赞技术团队
MyScale Blog
MyScale Blog
aimingoo的专栏
aimingoo的专栏
AI
AI

Deno

Deno 2.8 | Deno Claw Patrol: an open-source security firewall for agents | Deno Deno 2.7: Temporal API, Windows ARM, and npm overrides | Deno Build a dinosaur runner game with Deno, pt. 6 | Deno Build a dinosaur runner game with Deno, pt. 5 | Deno Deno Deploy is Generally Available | Deno Introducing Deno Sandbox | Deno Build a dinosaur runner game with Deno, pt. 4 | Deno Build a dinosaur runner game with Deno, pt. 3 | Deno Build a dinosaur runner game with Deno, pt. 2 | Deno React / Next.js Denial-of-Service Vulnerability: Deno Deploy users protected | Deno Deno 2.6: dx is the new npx | Deno Build a dinosaur runner game with Deno, pt. 1 | Deno React Server Functions / Next.js Vulnerability: Deno Deploy users protected | Deno My highlights from the new Deno Deploy | Deno Deno's Other Open Source Projects | Deno How Deno protects against npm exploits | Deno Help Us Raise $200k to Free JavaScript from Oracle | Deno Deno 2.5: Permissions in the config file | Deno Fresh 2.0 Graduates to Beta, Adds Vite Support | Deno Deno 2.4: deno bundle is back | Deno JavaScript™ Trademark Update | Deno What's coming to JavaScript | Deno A brief history of JavaScript | Deno Reports of Deno's Demise Have Been Greatly Exaggerated | Deno An Update on Fresh | Deno How Plaid migrated 100 services to a new database platform 5x faster with Deno | Deno Deno 2.3: Improved deno compile, local npm packages, and more | Deno Add JSR packages with pnpm and Yarn | Deno Zero-config Debugging with Deno and OpenTelemetry | Deno Exploring Art with TypeScript, Jupyter, Polars, and Observable Plot | Deno Deno v Oracle Update 3: Fighting the JavaScript Trademark | Deno Build a custom RAG AI agent in TypeScript and Jupyter | Deno How to get deep traces in your Node.js backend with OTel and Deno | Deno toranoana.deno #20 登録受付中(2025年3月14日) | Deno Node just added TypeScript support. What does that mean for Deno? | Deno The Dino 🦕, the Llama 🦙, and the Whale 🐋 | Deno Publish a lint rule, get a prize | Deno Deno 2.2: OpenTelemetry, Lint Plugins, node:sqlite | Deno If you're not using npm specifiers, you're doing it wrong | Deno How Deno's documentation is evolving | Deno Oracle justified its JavaScript trademark with Node.js—now it wants that ignored | Deno Introducing the JSR open governance board | Deno Intro to Wasm in Deno | Deno Announcing OpenAI on JSR | Deno Deno in 2024 | Deno Goodbye WinterCG, welcome WinterTC | Deno Build a SolidJS app with Deno | Deno Run your Next.js SSR app on Deno Deploy | Deno Solve Advent of Code 2024 with Deno and Win Prizes! | Deno Deno v. Oracle: Canceling the JavaScript Trademark | Deno Deno 2.1: Wasm Imports and other enhancements | Deno Build a Typesafe API with tRPC and Deno | Deno Self-contained Executable Programs with Deno Compile | Deno Build a Database App with Drizzle ORM and Deno | Deno Introducing your new JavaScript package manager: Deno | Deno Announcing Growthbook on JSR | Deno Build an Astro site with Deno | Deno How to convert CommonJS to ESM | Deno Announcing Deno 2 | Deno The Final Touches: What’s New In v2.0.0-rc.10 | Deno Announcing Stable V8 Bindings for Rust | Deno Deno 2.0 Release Candidate | Deno Secure, efficient private npm registries with Cloudsmith and Deno | Deno Painting the Plane as We Fly It: Designing JSR | Deno Introducing Web Cache API support on Deno Deploy | Deno Deno 1.46: The Last 1.x Release | Deno Protect your cloud spend with new Deno Deploy spend limits | Deno What we got wrong about HTTP imports | Deno Benchmarking AWS Lambda Cold Starts Across JavaScript Runtimes | Deno Announcing Supabase on JSR | Deno Deno 1.45: Workspace and Monorepo Support | Deno Introducing KV Backup for Deno Subhosting | Deno A Gentle Intro to TypeScript | Deno Announcing Hono on JSR | Deno How We Made the Deno Language Server Ten Times Faster | Deno How the Guardian uses Deno to audit accessibility and performance across their 2.7 million articles | Deno Introducing More Flexible Domain Association for Deno Subhosting | Deno The stabilization process of the Standard Library has begun | Deno Deno 1.44: Private npm registries, improved Node.js compat, and performance boosts | Deno How we built a secure, performant, multi-tenant cloud platform to run untrusted code | Deno The Deno Standard Library is now available on JSR | Deno How to document your JavaScript package | Deno Your Low Code Solution Needs an Escape Hatch | Deno Deno 1.43: Improved Language Server performance | Deno How Slack used Deno to save months of engineering effort in launching their new platform | Deno JSR Is Not Another Package Manager | Deno Announcing the Hookdeck SDK on JSR | Deno Announcing the Neon Serverless Driver on JSR | Deno An intro to TSConfig for JavaScript Developers | Deno How we built JSR | Deno How Netlify used Deno Subhosting to build a successful edge functions product | Deno Introducing Simpler Project Creation in Deno Deploy | Deno Deno 1.42: Better dependency management with JSR | Deno Introducing deployctl, the command line interface for Deno Deploy | Deno Introducing JSR - the JavaScript Registry | Deno How to add Monaco to a Next.js app and securely run untrusted user code | Deno Survey Results and Roadmap | Deno Deno 1.41: smaller deno compile binaries | Deno Webhooks suck, but here are alternatives | Deno
Fresh 2.3: Zero JS by default, View Transitions, and Temporal support | Deno
Bartek Iwańc · 2026-04-24 · via Deno

Fresh 2.3 is out, with over 100 commits from 20 contributors. This release makes the “zero JavaScript by default” promise actually hold, adds View Transitions support, pre-compiles middleware chains, and rounds out a long list of Vite integration fixes.

You can start a new project with:

or update an existing one with:

deno run -Ar jsr:@fresh/update

Zero JavaScript by default

Fresh has always said that pages ship no JavaScript unless they need to, but that wasn’t strictly true. Every page ended up with a small client-entry script to bootstrap the island reviver and partials engine, even when neither was used.

Thanks to Jeroen Akkerman in #3696, Fresh now checks whether the page actually uses islands or partials (f-client-nav) before injecting anything. If it doesn’t, the page ships with no <script> tag, no module preload headers, and no client-side bundle at all.

Fresh 2.2 Fresh 2.3
JavaScript (raw) ~14–22 KB 0 KB
JavaScript (gzip) ~5–9 KB 0 KB
Module preload headers 1+ 0
Inline boot <script> 1 0

There is nothing to configure. Static pages will just stop shipping JavaScript after upgrading.

View Transitions

The View Transitions API lets browsers animate between DOM states natively. Fresh 2.3 wires it up to the existing partials system, so you can opt in by adding one attribute:

<body f-client-nav f-view-transition>
  
</body>

Partial navigations will then be wrapped in document.startViewTransition() and you can customize the animation with regular CSS:

::view-transition-old(root) {
  animation: fade-out 0.2s ease-in;
}
::view-transition-new(root) {
  animation: fade-in 0.2s ease-out;
}

Or target individual elements:

.sidebar {
  view-transition-name: sidebar;
}
View Transitions between two pages in a Fresh app.

Browsers without support fall back to normal partial updates. See the View Transitions docs for more.

First-class WebSocket support

Fresh now has built-in WebSocket support (#3774). The quickest way to add a WebSocket endpoint is app.ws():

main.ts

const app = new App()
  .ws("/ws", {
    open(socket) {
      console.log("Client connected");
    },
    message(socket, event) {
      socket.send(`Echo: ${event.data}`);
    },
    close(socket) {
      console.log("Client disconnected");
    },
  });

For file-based routes, use ctx.upgrade() inside a GET handler. In managed mode, pass handlers and get the response back directly:

routes/api/ws.ts

export const handlers = define.handlers({
  GET(ctx) {
    return ctx.upgrade({
      message(socket, event) {
        socket.send(`Echo: ${event.data}`);
      },
    });
  },
});

There’s also a bare mode. Call ctx.upgrade() without arguments to get the raw WebSocket object, useful when you need to store sockets in a shared structure like a chat room:

routes/api/chat.ts

const clients = new Set<WebSocket>();

export const handlers = define.handlers({
  GET(ctx) {
    const { socket, response } = ctx.upgrade();

    socket.onopen = () => clients.add(socket);
    socket.onmessage = (event) => {
      for (const client of clients) {
        if (client.readyState === WebSocket.OPEN) {
          client.send(event.data);
        }
      }
    };
    socket.onclose = () => clients.delete(socket);

    return response;
  },
});

Non-WebSocket requests to a WebSocket route automatically get a 400 response. See the WebSocket documentation for the full API including idleTimeout and protocol options.

Vite integration improvements

A lot of this cycle went into making the Vite integration more robust, especially around npm package compatibility.

  • CJS-to-ESM transforms and process.env replacements are now handled by Vite directly, so we could drop two Babel passes from the build.
  • CJS handling in SSR dev mode has been improved, React compat aliasing works properly now, and resolve.alias is applied before Deno resolution. Packages like Radix UI work out of the box.
  • optimizeDeps.exclude is set up so Vite no longer creates a duplicate Preact instance during pre-bundling.
  • Vite asset URLs now include a cache-bust query param so immutable caching does the right thing (#3761).
  • Temp files are ignored by the Vite watcher, so editor swap files no longer crash the dev server (#3763).

Work in this area is continuing. #3767 removes the rest of the Babel transforms (~2,050 lines) and lets Vite handle CJS packages natively end to end. That should land shortly after 2.3.

CSP nonces and IP filtering

Two new security middleware ship with this release.

CSP nonce injection (#3709) generates a unique nonce per request and adds it to every inline <script> and <style> tag. The corresponding Content-Security-Policy header uses 'nonce-{value}' instead of 'unsafe-inline', so only scripts and styles that Fresh rendered are allowed to execute.

main.ts

import { csp } from "fresh";

app.use(csp({ useNonce: true }));

User-supplied CSP directives now override the defaults rather than duplicating them (#3724). See the CSP documentation for the full list of options.

IP filter middleware (#3035, thanks to Octo8080X) adds built-in IP-based allow/deny lists with CIDR support:

main.ts

import { ipFilter } from "fresh";

app.use(ipFilter({
  denyList: ["192.168.1.10"],
  allowList: ["192.168.1.0/24"],
}));

See the IP filter documentation for custom response handling and more examples.

OpenTelemetry: server-to-browser trace propagation

Fresh already instruments middleware, route handlers, and rendering with OpenTelemetry spans. In 2.3, it also injects a W3C traceparent meta tag into the HTML response (#3729), so browser-side telemetry SDKs can connect client spans to the server trace.

Enable tracing with Deno’s built-in OpenTelemetry support:

terminal

OTEL_DENO=true deno task start

Fresh will then automatically add the meta tag to every rendered page:

<meta
  name="traceparent"
  content="00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01"
/>

No code changes required. See the OpenTelemetry documentation for exporter configuration and the full list of instrumented spans.

Temporal API in islands

The Temporal API is landing in JavaScript engines, and Fresh now supports passing all eight Temporal types as island props:

  • Temporal.Instant
  • Temporal.ZonedDateTime
  • Temporal.PlainDate, PlainTime, PlainDateTime
  • Temporal.PlainYearMonth, PlainMonthDay
  • Temporal.Duration

You can pass a Temporal value from a route straight through to an island:

routes/event.tsx

export default function EventPage() {
  const date = Temporal.PlainDate.from("2026-04-24");
  return <Countdown target={date} />;
}

islands/Countdown.tsx

export default function Countdown(props: { target: Temporal.PlainDate }) {
  const today = Temporal.Now.plainDateISO();
  const days = today.until(props.target).days;
  return <p>{days} days to go</p>;
}
Passing Temporal values from a route to an island.

Multiple static directories

The staticDir option now accepts an array (#3759). When the same filename exists in multiple directories, the first entry wins. This is useful when a build step generates assets into a separate directory and you want to keep those separate from hand-authored files.

vite.config.ts

import { defineConfig } from "vite";
import { fresh } from "@fresh/plugin-vite";

export default defineConfig({
  plugins: [
    fresh({
      staticDir: ["static", "generated"],
    }),
  ],
});

See the static files documentation for more.

Loading indicators on form submissions

Loading indicators used to only work for link clicks. In 2.3 they work for form submissions too (#3753). Fresh checks the submitter element first (for example, the clicked button) and falls back to the form, so you can have per-button indicators when a form has multiple submit buttons:

import { useSignal } from "@preact/signals";

function MyForm() {
  const saving = useSignal(false);

  return (
    <form action="/save" f-partial="/partials/save">
      <button
        type="submit"
        ref={(el) => {
          if (el) el._freshIndicator = saving;
        }}
      >
        {saving.value ? "Saving..." : "Save"}
      </button>
    </form>
  );
}
Per-button loading indicators on a form submission.

Reverse proxy support

Apps behind nginx, Caddy, or a cloud load balancer can now opt into trustProxy so that ctx.url reflects the actual client-facing URL (#3757):

const app = new App({ trustProxy: true });

With this enabled, Fresh reads the X-Forwarded-Proto and X-Forwarded-Host headers and rewrites ctx.url accordingly. If your proxy terminates TLS and forwards X-Forwarded-Proto: https, ctx.url.protocol will be https: instead of http:. See the reverse proxy documentation for details.

deno create support

With Deno 2.7+, you can scaffold a new Fresh project using deno create (#3706):

The old deno run -Ar jsr:@fresh/init form still works but now shows a deprecation warning.

Bug fixes

A non-exhaustive list of the most impactful fixes in this release:

  • HttpError is now exposed for client-side code, with an optional message to keep bundle sizes down (#3080).
  • Routing: optional parameter routes no longer 404 (#2798), trailing slash mismatches no longer break static routes (#3721), middleware matches optional parameters in fs routing (#3726), and layouts apply correctly to index routes in programmatic routing (#3725).
  • Partials: forms without an explicit f-partial inside f-client-nav are no longer intercepted (#3722), search params are preserved through redirects (#3715), and data script tags are appended to <head> during partial navigation (#3720).
  • The <Head> component now works correctly when rendered on the client (#3252).
  • Active links now consider query parameters and respect existing aria-current attributes (#3755).
  • Better error messages for missing exports in file routes (#3718), warnings instead of crashes on invalid HTML nesting around islands (#3762), and warnings for Partials with append/prepend mode missing a key prop (#3738).
  • Pre-compiled middleware (#3104): middleware chains are now compiled once at startup instead of being assembled on every request.
  • Windows: paths are normalized in generated snapshot and server entry files (#3727).

What’s next

We’re continuing to improve Vite support: upgrading to Vite 8 with Rolldown (#3760) and removing the remaining Babel transforms entirely (#3767).

The other big focus is build-time prerendering (#3766). Mark a route with prerender: true and Fresh renders it to static HTML during the build. Dynamic routes can enumerate their paths too, effectively turning Fresh into a static site generator for pages that don’t need a server.

Follow along on GitHub.