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
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!