Invite-Only Early Access — Think Throo GitHub App is currently invite-only. Request access here.
2026February

tsdown, the elegant bundler for libraries powered by Rolldown

In this article, we review tsdown library. We will look at:

  1. What is tsdown?

  2. tsdown usage in cloudflare/agents.

Press enter or click to view image in full size

What is tsdown?

tsdown is the elegant bundler for libraries powered by Rolldown.

Fun fact: There is also tsup — The simplest and fastest way to bundle your TypeScript libraries.

Features

  • 🚀 Blazing fast: Build and generate declaration files powered by Oxc and Rolldown, incredibly fast!

  • ♻️ Powerful ecosystem: Support Rollup, Rolldown, unplugin plugins, and some Vite plugins.

  • ️🛠️ Easy to use: tsdown preconfigures everything you need to get started, so you can focus on writing code.

  • 🔄 Seamless migration: Compatible with tsup’s main options and features, ensuring a smooth transition.

Learn more about tsdown.

tsdown usage in cloudflare/agents

So I came across tsdown in the cloudflare/agents/scripts/build.ts and it is defined as shown below:

import { execSync } from "node:child_process";
import { build } from "tsdown";

async function main() {
  await build({
    clean: true,
    dts: true,
    entry: [
      "src/*.ts",
      "src/*.tsx",
      "src/cli/index.ts",
      "src/mcp/index.ts",
      "src/mcp/client.ts",
      "src/mcp/do-oauth-client-provider.ts",
      "src/mcp/x402.ts",
      "src/observability/index.ts",
      "src/codemode/ai.ts",
      "src/experimental/forever.ts"
    ],
    skipNodeModulesBundle: true,
    external: ["cloudflare:workers", "cloudflare:email"],
    format: "esm",
    sourcemap: true,
    fixedExtension: false
  });

  // then run oxfmt on the generated .d.ts files
  execSync("oxfmt --write ./dist/*.d.ts");

  process.exit(0);
}

main().catch((err) => {
  // Build failures should fail
  console.error(err);
  process.exit(1);
});

I recommend atlreast reading about the options used in the above code snippet at tsdown API reference about inline config.

So the build is configured with all the files that are supposed to be bundled in the main function and this is invoked at the end of build.ts but we haven’t found out yet where this script is called.

In agents/package.json, you will find the below:

"scripts": {
    "build": "tsx ./scripts/build.ts",
    "evals": "(cd evals; evalite)",

About me:

Hey, my name is Ramu Narasinga. I study codebase architecture in large open-source projects.

Email: ramu.narasinga@gmail.com

I spent 200+ hours analyzing Supabase, shadcn/ui, LobeChat. Found the patterns that separate AI slop from production code. Stop refactoring AI slop. Start with proven patterns. Check out production-grade projects at thinkthroo.com

References:

  1. rolldown/tsdown

  2. cloudflare/agents/packages/agents/scripts/build.ts

  3. https://github.com/egoist/tsup

  4. https://tsdown.dev/

  5. cloudflare/agents/packages/agents/scripts/build.ts

  6. tsdown.dev/reference/api/Interface.InlineConfig#entry

  7. cloudflare/agents/blob/main/packages/agents/package.json