Skip to main content
Deno 2 is finally here 🎉️
Learn more

denopack logo

Bundling and minification toolset for Deno


Preface

🦕📦 denopack is a CLI tool and a collection of plugins that for bundling Typescript code to be used with Deno or in the browser. This library uses the browser versions of Rollup (bundling) and Terser (compression/minification).

This library is made for Deno and is thus fully usable in Deno as a package or as a CLI app with deno install. No node_modules, npm/yarn scripts, etc are needed.

Contents

Goals

There is absolutely nothing wrong with deno bundle, but in its current state it is missing several features that are present in the NodeJS ecosystem. The goal is to provide an alternative bundling method that can - together with a plugin system, extending functionality - provide several key wishlist features without turning to Node:

  • Tree shaking comes built-in with Rollup
  • Minification by the usage of the Terser plugin
  • Source Maps (should also come built-in with Rollup, coming soon)
  • Lock file support, checking checksums from the lockfile against loaded code
  • File watching (pretty sure this can be implemented, coming soon)

More to come, also see the deno bundle roadmap/wishlist over at denoland/deno/issues/4549

CLI

Installation

deno install --unstable --allow-read --allow-write --allow-env --allow-net -n denopack https://cdn.jsdelivr.net/gh/denofn/denopack@latest/cli.ts
eggs install --unstable --allow-read --allow-write --allow-env --allow-net -n denopack https://x.nest.land/denopack@0.3.0/cli.ts

NOTE: denopack uses unstable Deno APIs. These APIs are not final and may break, but this does mean --unstable is mandatory!

Usage

Usage:
  $ denopack -i mod.ts

Options:
  -v, --version                Display version number
  -i, --input <pathToFile>     The input file (most likely mod.ts)
  -o, --output [pathToFile]    The output file name
  -d, --dir [pathToDir]        The output directory
  -c, --config [pathToConfig]  The config file. Use --defaultConfig for default values
  -p, --print                  Prints the generated bundle to stdout
  --defaultConfig              Prints the default config to stdout
  -h, --help                   Display this message

Examples:
denopack -i mod.ts
denopack -i mod.ts -o bundle.js
denopack -i mod.ts --dir dist
denopack -c denopack.config.ts
denopack -i mod.ts -o out.js --dir dist -c denopack.config.ts

Usage with script runners

In case you don’t want to globally install denopack, but want to use it locally with script runners: this is absolutely, totally possible since denopack uses 0 NodeJS specific code!

Script runners that should work out-of-the-box:

# example

scripts:
  start: deno run --unstable --allow-read --allow-write https://cdn.jsdelivr.net/gh/denofn/denopack@latest/cli.ts
vr run start -i mod.ts -o bundle.js
#example

scripts:
  start:
    file: https://cdn.jsdelivr.net/gh/denofn/denopack@latest/cli.ts
    deno_options:
      allow-read: true
      allow-write: true
      unstable: true
denox run start -i mod.ts -o bundle.js
{
  "config": {
    "start": "--unstable --allow-read --allow-write https://cdn.jsdelivr.net/gh/denofn/denopack@latest/cli.ts -i mod.ts -o bundle.js"
  }
}
Commands start

Permissions

NOTE: both denopack and its plugins use unstable Deno APIs. These APIs are not final and may break, but this does mean --unstable is mandatory!

The CLI itself can run with a base permission of --allow-read, printing to stdout with the -p flag. Writing to file naturally requires --allow-write.

Additionally, the various built-in plugins can require extra permissions like --allow-net and --allow-env. More info can be found here.

Config file

Importing a Rollup config file is supported using the -c <path/to/config> flag and follow the same conventions as Rollup:

  • use default export for your config
  • ideally call it rollup.config.ts or denopack.config.ts

Plugins

Since the bundling logic - aside file system/network access - is handled by Rollup, the remaining core functionality of denopack is based around plugins that use Deno APIs for key features.

A list of included plugins and a collection of strategies are included in the plugin directory. Documentation from Rollup regarding plugins is available on their docs site.

Usage

If you only need plugins or hooks - for example to create a config file - you can import straight from the mod.ts in the plugin directory.

import /* whatever plugins/hooks are needed */ "https://cdn.jsdelivr.net/gh/denofn/denopack@latest/plugin/mod.ts";

export default {
  file: "mod.ts",
  plugins: [
    /* whatever plugins or hooks were imported */
  ],
};

Usage without CLI

If you want to handle the building/bundling yourself, the toplevel mod.ts also includes rollup that exposes the Rollup Javascript API and several typings.

import {
  rollup /* whatever plugins/hooks are needed */,
} from "https://cdn.jsdelivr.net/gh/denofn/denopack@latest/mod.ts";
import type { RollupOptions } from "https://cdn.jsdelivr.net/gh/denofn/denopack@latest/mod.ts";

Just like the CLI, you can use it out-of-the-box with deno run or script runners like the ones mentioned up above.

Contributing

  • If you are using vscode, install and enable the required extensions.
    • If you are not using vscode, sort your imports and use the following prettier settings:
      • semi: true
      • singleQuote: false
      • printWidth: 100
      • trailingComma: “es5”
      • tabWidth: 2
      • useTabs: false
  • Functions, constants and variables are always camelCase
  • Classes are allowed to be PascalCase
  • Extract shared code to util
  • Code that is not a plugin or hook lives in cli

Contributing denopack plugins

Contributing a plugin to the denopack repo is not only extremely welcomed, it’s even encouraged. That does mean a few conventions are in order, extending from the existing Rollup conventions these are:

  • Plugins should have a clear plugin name with a denopack-plugin- prefix
  • Plugin functions are always camelCased
  • Plugins and their documentation should be stored in a separate folder inside the plugin directory
  • Optionally also indicating what the most impactful action is (resolve, load, transform, …). The typescriptCompile plugin is an obvious exception, but do take a look at the naming of the other plugins
  • Use async Deno APIs (readFile not readFileSync, etc.)
  • Document your plugin in English and detail what flags are required! Here’s an example

Contributing denopack hooks

Contributing a hook follows the following conventions:

  • Hooks start with the keyword use
  • Hooks are always camelCased
  • Hooks are stored inside of hooks.ts
  • Hooks are always functions and always return an array of plugins
  • Using plugins that accept configuration options in hooks should always be allowed to pass config down to that plugin
  • Configuration options are stored in one object containing all configuration options, see hooks.ts for examples

Acknowledgements

  • Reddit user u/HarmonicAscendant - unrelated to this library - who coined the name name Denopack
  • The sauropod and package emoji’s courtesy of Twemoji