Library / SDK
jsr-io/jsr avatar
jsr-io/jsr

JSR: Open-Source JavaScript and TypeScript Package Registry

The open-source package registry for modern JavaScript and TypeScript

2,974 stars173 forksRustMIT

At a glance

What is it?
JSR is the open-source package registry that powers jsr.io. It is designed as a modern alternative to npm for JavaScript and TypeScript packages, with native TypeScript support, Deno integration, and an npm compatibility layer. The server runs on Cloudflare Workers and Google Cloud Run, and the full codebase is MIT-licensed and self-deployable.
Who is it for?
JSR is worth running locally if you are contributing to the registry itself, testing behavior against your own packages, or studying how a modern package registry is architected at scale. The codebase covers the full infrastructure path from package publishing to npm compatibility tarball generation, and the architecture documentation in architecture.md explains the design decisions.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 7 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What JSR Is and Who It Is For

JSR is the registry that serves packages at jsr.io. It is designed for modern JavaScript and TypeScript development, with first-class TypeScript support, documentation generation from source code, and compatibility with npm so that packages published to JSR can be consumed by projects that use npm, yarn, or pnpm.

The README notes four design goals: robust, low maintenance, cheap, and open source. The open-source aspect is the reason the codebase is publicly available. Engineers who want to contribute to the registry, understand how the infrastructure works, or run a local development environment to test their contributions are the primary audience for the repository itself.

Users publishing or consuming packages from jsr.io do not need this repository. The docs at jsr.io/docs cover the user-facing API. This repository is for the registry's own development. The setup process references @denoland employees as a distinct contributor group with internal tooling access, and the frontend is built with Fresh, Deno's web framework, reflecting the registry's close connection to the Deno ecosystem.

How the Registry Infrastructure Works

The architecture separates concerns across several layers, as documented in architecture.md.

Package modules, metadata, and npm compatibility tarballs are all stored on Cloudflare R2. R2 serves these artifacts directly at request time, meaning the PostgreSQL database is not in the critical path for serving registry requests. The database runs on Google Cloud SQL in a highly available configuration, but it is used for management operations, not for the hot path that serves package downloads.

The management API is written in Rust and runs on Google Cloud Run. It handles package publishing, metadata updates, and administrative operations. The frontend is built with Fresh, the Deno web framework, and runs as a Cloudflare Worker. The three public hostnames (jsr.io, api.jsr.io, npm.jsr.io) are all served through a Cloudflare Workers load balancer that routes module and metadata requests straight to R2 and proxies API requests to the Rust backend.

Search is powered by Algolia. Distributed tracing uses Google Cloud Trace in production and Jaeger in the development environment. The docker-compose.yml in the repository runs PostgreSQL 15 and Jaeger for local development:

yaml
services:
  postgres:
    image: postgres:15
    command: postgres -c 'max_connections=1000'
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
      POSTGRES_DB: registry
    ports:
      - 5432:5432

Setting Up a Local Development Environment

Two setup modes are available: frontend only, which connects to the production API, and full stack, which runs both the API and frontend locally.

For frontend-only development:

sh
deno task dev setup frontend

Then run the frontend against the production API:

sh
deno task prod:frontend

The registry becomes accessible at http://jsr.test. This is the recommended path for frontend changes since it avoids the full Rust and database setup.

For full stack development, additional prerequisites are needed: Deno, Rust, Docker and docker-compose on Linux or PostgreSQL via Homebrew on macOS, and the sqlx CLI installed with `cargo install sqlx-cli`. A GitHub App must also be created with the callback URL `http://jsr.test/login/callback` to handle OAuth. Configuration goes into api/.env.

With prerequisites in place, run setup:

sh
deno task dev setup

This verifies prerequisites, adds the jsr.test, api.jsr.test, and npm.jsr.test hostnames to /etc/hosts, creates the registry database, and runs migrations. Then start all services:

sh
deno task dev

The running terminal accepts commands: `restart <name|all>` restarts one service or all of them, and `quit` or Ctrl+C shuts everything down.

Publishing and Populating the Local Registry

Publishing a package to the local development environment uses the JSR_URL environment variable to redirect to the local instance:

sh
JSR_URL=http://jsr.test deno publish

For filling the local registry with a realistic volume of packages, the README recommends publishing the deno_std standard library. This requires first making your account a staff user or admin through a direct psql query:

sh
psql registry

Then update the users table to set is_staff true for your account, assign the std scope through the admin panel, clone deno_std, and publish all packages with JSR_URL pointing to the local instance.

Database migrations run with:

sh
deno task db:migrate

Documentation generation is handled through the deno_doc project rather than inline in the jsr codebase. Contributors who need to change documentation rendering should open pull requests against the deno_doc repository. Using a local deno_doc clone requires adding a patch override in the root Cargo.toml before running the jsr API locally.

JSR vs npm: Different Design Points

npm is the registry that has served the JavaScript ecosystem for over a decade and is owned by GitHub (Microsoft). Every package published to npm is a CommonJS or ESM tarball with a package.json. TypeScript types are either bundled or published separately as @types/* packages.

JSR is designed for native TypeScript: packages can publish TypeScript source directly, and the registry generates documentation from that source. It also maintains an npm compatibility layer through npm.jsr.io, where JSR packages are accessible as tarballs. This means a package published to JSR can be installed with npm, yarn, or pnpm by specifying the npm.jsr.io registry path, without the package author having to manually maintain a separate npm publish step.

The key practical difference for contributors is that JSR requires Deno for development tooling while npm packages are typically authored in a Node.js environment. The two registries can coexist, and many packages are available on both. JSR does not replace npm in the sense of migrating existing packages; it offers an alternative publishing target with different ergonomics for TypeScript-first projects.

License and Maintenance

The repository is licensed under MIT. The last push was on 2026-09-24. The repository is not archived. There are no GitHub releases in the repository, which reflects the continuous deployment model of a hosted service rather than versioned binary releases.

The Cargo.toml workspace includes three members: api, api/macros, and crates/jsr_types. The Deno frontend dependencies are tracked in deno.lock. The .licenserc.json file suggests automated license header checks are in place for contributions.

Contributing to the project requires signing off on commits and opening pull requests. The README targets two groups of contributors explicitly: Deno employees who have access to an internal .env file from 1Password, and external contributors who must create their own GitHub App and configure credentials manually.

Editorial conclusion

JSR is worth running locally if you are contributing to the registry itself, testing behavior against your own packages, or studying how a modern package registry is architected at scale. The codebase covers the full infrastructure path from package publishing to npm compatibility tarball generation, and the architecture documentation in architecture.md explains the design decisions. It is not a drop-in alternative for teams who need an on-premises private registry for internal packages; the setup requires Deno, Rust, Docker or PostgreSQL, sqlx, and a GitHub App for OAuth, which is more infrastructure than most internal-use cases warrant. For contributing documentation generation, changes should go through the deno_doc repository rather than directly into jsr.

Frequently asked questions

What does JSR stand for?

In the context of jsr.io, JSR stands for JavaScript Registry. It is the name of the open-source package registry for JavaScript and TypeScript that serves packages at jsr.io.

How does JSR differ from npm?

JSR supports native TypeScript source publishing and generates documentation from source code. It also maintains an npm compatibility layer so JSR packages can be installed using npm, yarn, or pnpm. npm requires compiled JavaScript or bundled types; JSR accepts TypeScript source directly.

Can I run a local copy of the JSR registry?

Yes. The repository includes setup scripts for running the full stack locally using Deno, Rust, PostgreSQL, and Docker. The frontend-only setup is simpler and connects to the production API while running the Fresh frontend locally.

Official sources

  1. Issues
  2. jsr-io/jsr on GitHub
  3. License: MIT
  4. Project website
  5. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/jsr-io-jsr.svg)](https://hysenlabs.com/projects/jsr-io-jsr)