npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@rm30/tsconfig

v0.1.0

Published

Shared RM30 TypeScript configurations — base, expo, next, node-lib.

Readme

@rm30/tsconfig

Shared TypeScript configurations. Four, matching the four shapes of code in the workspace.

pnpm add -D @rm30/tsconfig

Declare it in every package that extends it, not only at the monorepo root. Root-only works today because both Expo monorepos set nodeLinker: hoisted, which flattens node_modules so a nested package resolves upward into it. A project on pnpm's default strict linker would not, and a package should declare what it uses regardless.

| Config | For | |---|---| | @rm30/tsconfig/base.json | Everything else builds on this. Strictness and interop only — no emit decisions, no JSX. | | @rm30/tsconfig/next.json | A Next.js app. | | @rm30/tsconfig/expo.json | An Expo app — see the note below, it is used differently. | | @rm30/tsconfig/node-lib.json | A Node package that emits declarations (Firebase functions, a published lib). |

include, exclude and paths stay in the project

None of these configs set include or exclude, and that is not an oversight. TypeScript resolves relative paths against the config file they are written in, so an include: ["src"] shipped from here would resolve inside node_modules/@rm30/tsconfig/ and match nothing. The same goes for paths, which points at the project's own directories anyway.

So every project declares its own file set:

{
  "extends": "@rm30/tsconfig/next.json",
  "compilerOptions": {
    "paths": { "@/*": ["./src/*"] }
  },
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
  "exclude": ["node_modules"]
}

Expo app

Expo ships its own base, and it is not optional — it carries the React Native type resolution. So an Expo app extends both, ours last:

{
  "extends": ["expo/tsconfig.base", "@rm30/tsconfig/expo.json"],
  "compilerOptions": {
    "paths": { "@/*": ["./src/*"] }
  }
}

Array extends needs TypeScript 5.0+; later entries win.

expo.json deliberately does not extend base.json. It would have to reach expo/tsconfig.base from inside node_modules/@rm30/tsconfig/, where pnpm's symlinked store gives it no view of the consuming project's expo — so the extend would resolve in development and break for anyone else. Composing the two in the project keeps resolution where the packages actually are.

Node library

{
  "extends": "@rm30/tsconfig/node-lib.json",
  "compilerOptions": {
    "outDir": "lib",
    "rootDir": "src"
  }
}

outDir and rootDir stay local — they are layout, not policy.

Note that most internal packages should not use this. A package consumed only inside its own monorepo should be source-direct: main and types pointing at src/index.ts, no build step at all. Metro, Next and tsup all read TypeScript from source, so compiling buys nothing and costs a build that CI must run before anything type-checks. node-lib is for the cases that genuinely emit — Firebase functions, or a package published to npm.

What base sets

target/lib ES2022, module ESNext, moduleResolution bundler, strict, isolatedModules, esModuleInterop, allowSyntheticDefaultImports, resolveJsonModule, forceConsistentCasingInFileNames, skipLibCheck.

moduleResolution: bundler is deliberate. The old node (node10) mode is deprecated as of TypeScript 6 and errors without an ignoreDeprecations escape hatch, and every RM30 package is either bundled or consumed by a bundler, so bundler is simply the accurate description.