Arek Nawo Hobbyist. Programmer. Dreamer. Freelancer. JavaScript and TypeScript lover. 👍 World-a-better-place maker. 🌐

Exploring Velociraptor, Deno’s npm-style script runner

4 min read 1346

Exploring Velociraptor, Deno's npm-style script runner

Node.js’s younger sibling, Deno, has been evolving. Since its official, buzzy release in May 2020, a lot has changed. The hype has toned down, the runtime has been improved, and the community, alongside the whole module ecosystem, has started to form.

However, even with these changes, Deno still isn’t the “Node.js killer” some might have seen it as. Sure, it comes with great features, like first-class TypeScript support, a secure permission-based system, and URL-based module loading, but it lags behind Node in mind-share and a few basic aspects.

One example of such a feature is a script runner. In Node, there’s package.json, in which you can specify your scripts.

"scripts": {
    "dev": "vite",
    "build": "vite build",
    "serve": "vite preview"
  }
}

The problem is, there’s no inbuilt package.json or any alternative in Deno. You have to type out the full command any time you want to use it. Tons of config flags don’t make this any better:

deno run --allow-read --allow-write --allow-net --reload example.ts

The way around that is to use a third-party script runner, like Velociraptor. Let’s see what features it has, how it works, and how it can make working with Deno that much better!

An introduction to Velociraptor

Velociraptor is arguably the most popular script runner for Deno, with about 500 GitHub stars at the time of this article’s publication. It is inspired by package.json’s scripts and offers a similar out-of-the-box experience to its Node counterpart, but also comes with additional, Deno-specific features.

Installation

You can install Velociraptor from deno.land/x, like any other module:

deno install -qAn vr https://deno.land/x/[email protected]/cli.ts

It’s recommended to use vr while assigning a name to the executable. Using a different name may result in some known issues with Git hooks.

Configuration

Next, create your configuration file — the package.json replacement. It could be either a scripts or a velociraptor file with one of the following extensions:

  • yml / yaml
  • json
  • ts

Here are examples of different config files:

scripts.yaml

scripts:
  start: deno run --allow-net server.ts
  test: deno test --allow-net server_test.ts

scripts.json

{
  "scripts": {
    "start": "deno run --allow-net server.ts",
    "test": "deno test --allow-net server_test.ts"
  }
}

script.ts

export default {
  scripts: {
    start: "deno run --allow-net server.ts",
    test: "deno test --allow-net server_test.ts",
  },
};

We’ll stick with yaml for the rest of this post.

Besides the basic, compact form, scripts can also be defined as objects that allow for passing additional options, like desc for describing the script’s purpose or watch for reloading the script on file change.

scripts:
  start:
    desc: Runs the server
    cmd: deno run --allow-net server.ts
    watch: true

In object format, you specify the actual command under the cmd property.

The Velociraptor CLI

Alongside the configuration file, Velociraptor’s CLI is its most important feature. It’s your yarn or npm run equivalent for the Deno world.



Running plain vr in your terminal will output all defined scripts, while vr run <script> or vr <script> will run the selected script.

vr # list available scripts
vr run start # run "start" script
vr start # more concise way of running "start" script
vr start --prod # run "start" script with "prod" argument

Besides running scripts, Velociraptor also provides an export command for outputting one or more scripts as a standalone executable for use in environments where Velociraptor is not installed.

vr export start # export "start" script
./bin/start --prod # run exported script with "prod" argument

vr export start -o output # change output directory from default "bin"

Configuration features

While defining scripts and running them from the CLI should be enough in most cases, Velociraptor goes far beyond that. With its additional features, using a script runner in Deno becomes a much better experience.

Passing Deno CLI options

Velociraptor allows you to specify some of your Deno CLI options in a clean, structured way with dedicated config properties.

Permissions

You can specify Deno permissions in an array or object for all scripts at the upper-most allow field, or on a script-by-script basis.

allow:
  - read
  - write

scripts:
  start:
    cmd: server.ts
    allow:
      net: 127.0.0.1

Config files

You can also provide paths to files like tsconfig.json, importmap.json, lock files, and PEM certificates for SSL under separate config entries.

scripts:
  start:
    cmd: server.ts
    cert: certificate.pem
    lock: lock.json
    imap: importmap.json
    tsconfig: tsconfig.json

Apart from the above, there are many more additional options you can specify. These include:

  • inspect for attaching the debugger
  • reload for recompiling TypeScript (either everything or only specified modules)
  • log for specifying the log level
  • v8Flags for passing options to the V8 engine
  • Many more boolean flags, like unstable, cachedOnly, and others

Check out the official Velociraptor documentation for more details.

Passing environment variables

Apart from the Deno CLI options, there are also dedicated fields for environment variables. This includes:

  • env for listing the variables in the config file directly
  • envFile for specifying a dotenv file (or list of files) to load the variables from

The options can be specified at both the top and script levels and will be combined so that the script receives all needed variables.


More great articles from LogRocket:


# for all scripts
envFile:
  - .env
env:
  PORT: 8081

scripts:
  start:
    cmd: deno run --allow-net server.ts
    # script-specific
    envFile: .start_env
    env:
      PORT: 8082

Composite scripts

One more great feature of Velociraptor allows you to run multiple scripts at once. With composite scripts, complex commands filled with && and other operators can be replaced with a clean list of scripts.

scripts:
  start:
    - deno run one.ts
    - deno run two.ts
  test: # With script objects
    - deno test test_one.ts
    - cmd: deno test test_two.ts
      tsconfig: tsconfig.json

The example above runs scripts serially, in order. To run them in parallel, use the pll option.

scripts:
  start:
    pll: # In parallel
      - deno run one.ts
      - deno run two.ts

pll can be combined with a serial script list to form even more complex execution flows.

scripts:
  start:
    - pll:
        - deno run one.ts
        - deno run two.ts
    - deno run three.ts

This enables a new set of possibilities, having complex script flows defined and executed clearly, right from the config file.

Using Git hooks with Velociraptor

Velociraptor comes with inbuilt support for Git hooks. It allows you to effortlessly integrate your scripts with Git hooks and share them with others working on the same repo.

To link a single script to a Git hook, add the gitHook property to it.

scripts:
  format:
    cmd: deno fmt
    gitHook: pre-commit

To attach more than one script to a Git hook, you can use gitHook alongside composite scripts.

With hooks set up, you can install them by running the vr command. If you’d like to prevent this behavior (e.g., for CI configuration), set the VR\_HOOKS environment variable to false.

Tooling integrations

For more advanced workflows, Velociraptor integrates with GitHub Actions, thanks to a setup-velociraptor action. When combined with setup-deno, you can use vr commands right from your Actions.

steps:
  - uses: denoland/[email protected]
  - uses: jurassiscripts/[email protected]
  - run: vr ...

Editor support

You can install the dedicated extension for autocompletion and other code assistance features for Velociraptor in VS Code. This will autocomplete configuration options in both yaml and json files.

You can still get autocompletion in other editors and IDEs by using TypeScript for your configuration file, alongside proper type annotation.

import { ScriptsConfiguration } from "https://deno.land/x/[email protected]/mod.ts";

const config: ScriptsConfiguration = {
  scripts: {
    start: "deno run --allow-net server.ts",
    test: "deno test --allow-net server_test.ts",
  },
};

export default config;

Bottom line

With a great, feature-packed script runner like Velociraptor, Deno becomes much more enjoyable to use. All of your scripts are just vr <script> away; Git hooks integration couldn’t be simpler; and building complex script flows is easy, thanks to composite scripts, structured options, and autocompletion.

If you haven’t already, check out Velociraptor over on GitHub and give it a try!

Get setup with LogRocket's modern error tracking in minutes:

  1. Visit https://logrocket.com/signup/ to get an app ID.
  2. Install LogRocket via NPM or script tag. LogRocket.init() must be called client-side, not server-side.
  3. $ npm i --save logrocket 

    // Code:

    import LogRocket from 'logrocket';
    LogRocket.init('app/id');
    Add to your HTML:

    <script src="https://cdn.lr-ingest.com/LogRocket.min.js"></script>
    <script>window.LogRocket && window.LogRocket.init('app/id');</script>
  4. (Optional) Install plugins for deeper integrations with your stack:
    • Redux middleware
    • ngrx middleware
    • Vuex plugin
Get started now
Arek Nawo Hobbyist. Programmer. Dreamer. Freelancer. JavaScript and TypeScript lover. 👍 World-a-better-place maker. 🌐

Leave a Reply