Introduction to JSR

Introduction to JSR


typescript npm bun

One things we love about Web Development is that we share each others code. An that’s what we’re going to do in this post today. We will build a basic package that can be installed with package managers like pnpm, bun, deno, npm or even cloudflare worker.

The package would be secure, written in TS with documentation. Finally, we will automate publishing our code to the package repository with Github Action. However if you would like to tryout the final package, checkout Lorem AI 🤖

Prerequisite

We need the following setup before hand for this to work

  • A github account for CI deployments…duh!

  • Goto JSR’s Website to create an account and a role for your projects. You can learn more about roles here

  • A JavaScript runtime ie: Node.js or Deno or Bun etc…

Setup a new project

I would be using Bun for this tutorial but you can use any package manager that creates a any JavaScript package manager, and in any project with a node_modules folder.

Run the following command to initialize a new bun project:

bun init

Following the prompts from bun will scaffold the starter project for you.

# created a minimal typescript project.

 + index.ts (entrypoint)
 + .gitignore
 + tsconfig.json (for editor auto-complete)
 + README.md

Usage:

Let’s update the index.ts code in your IDE. Add a package to using one of the commands below.

# bun (use any of npx, yarn dlx, or pnpm dlx)
bunx jsr add @deejaydev/lorem-ai


# or a deno project
deno add @deejaydev/lorem-ai

Tip: You can even import packages with tools that natively support JSR, Currently, the only tool that natively supports JSR is Deno like this👇

// example using the jsr: scheme in deno
import { camelCase } from 'jsr:@deejaydev/lorem-ai'

Now you can use the package loremAI in your project as seen in the example below.

import { loremAI } from '@deejaydev/lorem-ai'

const API_KEY = Bun.env.GEMINI_API_KEY

async function run() {
  try {
    const sentence = await loremAI(API_KEY, 50)
    console.log(sentence) // random sentence with 50 words
  } catch (error) {
    console.error('Error generating sentence:', error)
  }
}

run()

Now let’s build ours and build a tiny lib so we don’t have to rewrite the same code in other projects, even better share with developers over the internet.

To do that we need a to create and test our lib then we can deploy it to a repository for JavaScript / TypeScript packages.

Let’s replace the previous code with this

/**
 * A module function to calculate numbers.
 * @module
 */

/**
 * A very simple function to add numbers.
 * @param a 1st number you want to add
 * @param b 2nd number you want to add
 */

export const add = (a: number, b: number) => a + b

Next we must set up the package for deployment. Create a jsr.json file if you don’t have it already. The jsr.json contains package metadata like the name, version, and entrypoint(s).

Note: The exports field tells JSR which modules should be importable by users of your package.

// jsr.json / deno.json
{
  "name": "@deejay/tiny-pack",
  "version": "0.1.0",
  "exports": "./mod.ts"
}

Finally, run the following to publish your package. You will be prompted to authenticate with JSR, and then your package will be published to the Javascript Repository (JSR).

 bunx jsr publish

You can run jsr publish with the --dry-run flag This will print out a list of files that will be published, but stop short of actually publishing to the registry.

Automate publishing

Create a github action in your project add the following directory: .github/workflows/publish.yml. then add the following code to the publish.yml file.

# .github/workflows/publish.yml

name: Publish
on:
  push:
    branches:
      - main

jobs:
  publish:
    runs-on: ubuntu-latest

    permissions:
      contents: read
      id-token: write # The OIDC ID token is used for authentication with JSR.

    steps:
      - uses: actions/checkout@v4

      - name: Publish package
        run: npx jsr publish --allow-dirty

With that done, whenever you publish your code to GitHub your package will be punished to JSR…Nice one! Now your package is live. If you enjoyed this article, you might like to get my FREE cheat-sheet 👉 10 TypeScript One-Liners . Happy Learning!