{"id":13998440,"url":"https://github.com/tsmodule/tsmodule","last_synced_at":"2025-07-23T06:31:51.725Z","repository":{"id":37247082,"uuid":"448083696","full_name":"tsmodule/tsmodule","owner":"tsmodule","description":"Create standardized TypeScript ESM packages for Node or browser.","archived":false,"fork":false,"pushed_at":"2023-07-19T14:27:55.000Z","size":1730,"stargazers_count":81,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-11-29T11:07:49.332Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@tsmodule/tsmodule","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tsmodule.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2022-01-14T19:25:30.000Z","updated_at":"2024-08-20T08:45:31.000Z","dependencies_parsed_at":"2024-01-15T19:45:33.732Z","dependency_job_id":"c58cd0c5-4f9d-490e-8552-525e7142bd3c","html_url":"https://github.com/tsmodule/tsmodule","commit_stats":null,"previous_names":[],"tags_count":219,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tsmodule%2Ftsmodule","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tsmodule%2Ftsmodule/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tsmodule%2Ftsmodule/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tsmodule%2Ftsmodule/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tsmodule","download_url":"https://codeload.github.com/tsmodule/tsmodule/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":227245178,"owners_count":17753239,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-09T19:01:40.554Z","updated_at":"2024-11-30T00:31:38.721Z","avatar_url":"https://github.com/tsmodule.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"tsmodule.png\"\u003e\n  \u003ch1\u003eTypeScript Module Toolkit\u003c/h1\u003e\n\u003c/div\u003e\n\nCreate standardized TypeScript ESM packages for Node or browser. Includes\n`--bundle` and `--binary` build options, powered by\n[**esbuild**](https://github.com/evanw/esbuild).\n\n**Table of contents**\n\n\u003c!-- toc --\u003e\n\n- [Installation](#installation)\n  * [Requirements (global)](#requirements-global)\n  * [Existing projects](#existing-projects)\n  * [New projects](#new-projects)\n- [Purpose](#purpose)\n  * [Create ESM packages using TypeScript](#create-esm-packages-using-typescript)\n  * [Develop projects in real-time](#develop-projects-in-real-time)\n  * [Build to optimized ES modules](#build-to-optimized-es-modules)\n  * [Optimize NPM dependencies with `-b, --bundle`](#optimize-npm-dependencies-with--b---bundle)\n  * [Run TypeScript directly](#run-typescript-directly)\n- [Use Cases](#use-cases)\n  * [Generic TypeScript library](#generic-typescript-library)\n  * [React component library (using Next.js)](#react-component-library-using-nextjs)\n- [Footnotes](#footnotes)\n  * [Module configuration](#module-configuration)\n    + [Index exports](#index-exports)\n    + [Package.json export](#packagejson-export)\n- [License](#license)\n\n\u003c!-- tocstop --\u003e\n\n## Installation\n\n### Requirements (global)\n\n- Node v14+ (for ESM support)\n- PNPM\n\n### Existing projects\n\nTo convert an existing project (and install standardized package.json settings,\ndependencies, and config files), run this in your project directory:\n\n```bash\ntsmodule convert\n```\n\n\u003csub\u003eYou will need to move all TS source files to `src/` if they are not there\nalready. Ensure you read the [module\nconfiguration notes](#module-configuration) regarding \"index exports\" as it\nrelates to importing downstream.\u003c/sub\u003e\n\n### New projects\n\nCreate a new package with:\n\n```\ntsmodule create [--react] project-name\n```\n\n## Purpose\n\n### Create ESM packages using TypeScript\n\n`tsmodule create` exists to bootstrap a Node or React project in as little time\nas possible. The created packages are modular, and `tsmodule create --react`\nwill create a modular Next.js project with [importable components and styles](#react-component-library-using-nextjs).\n\nReady out of the box:\n\n  - package.json scripts\n  - TypeScript, ESLint configs (Tailwind, PostCSS for React)\n  - CI/CD with GitHub Actions\n\n### Develop projects in real-time\n\nBuild in dev mode and watch for changes:\n\n```\ntsmodule dev\n```\n\n### Build to optimized ES modules\n\nProduction builds are minified ESM, with support for `my-package/a/b/c` path\nresolution (see [Module configuration](#module-configuration) below).\n\n```\ntsmodule build [--bundle]\n```\n\n**All projects:**\n\n  - Emit pure ESM, no polyfilling to CJS\n  - Emit ESNext by default, no polyfilling to older feature sets\n\n**React projects created with `create --react`:**\n\n  - Bundle CSS by default\n  - Use Tailwind by default\n\n### Optimize NPM dependencies with `build --bundle`\n\nWith `-b, --bundle` mode, all entry points are compiled \"in-place\" and runtime NPM dependencies will generally not be needed as they will be inlined. If you build in bundle mode, you can move your dependencies to devDependencies, as the only thing that will be needed to run any/all compiled-in-place entry point(s) in your module are the bundles themselves.\n\nTSModule itself builds with `-b, --bundle` flag, and requires only three runtime NPM dependencies:\n\n1. `esbuild`, which does the heavy lifting for the build process, does not allow itself to be bundled;\n2. `typescript`, so TSModule can use the built `tsc` binary to generate `.d.ts`\n   type declarations during builds; and\n3. `pkg`, for building binaries with `build --binary` (a specific standalone\n   bundle mode).\n\n\u003csub\u003eNote: Bundling every entry point in place may not be what you want, i.e. if you\nonly have a single entrypoint. In these cases, `tsmodule build -b src/index.ts`\nis more appropriate.\u003c/sub\u003e\n\n### Build executable binaries with `build --binary`\n\nUses Vercel's [`pkg`](https://github.com/vercel/pkg) to build binaries from\n`src/bin.ts`.\n\n\u003csub\u003e**IMPORTANT:** This requires coercing to CJS, which is not possible if your\nprogram uses top-level await. For now, replace with async closures and monitor\n[this issue](https://github.com/vercel/pkg/issues/1291) for updates on full ESM\nsupport.\u003c/sub\u003e\n\n### Run TypeScript directly\n\n```\ntsmodule file.ts\n```\n\n  - Uses Node module loader to resolve TS at runtime\n  - Executable TypeScript files with `#!/usr/bin/env tsmodule`\n\n## Use Cases\n\nBelow are some example use cases of TS modules in practice.\n\n### Generic TypeScript library\n\nThe most common type of library will be a TS module with generic TypeScript\nexports in `src/**/index.ts`, e.g.\n[`universal-shell`](https://github.com/ctjlewis/universal-shell), a Promise wrapper\naround `child_process.spawn` that's used in tsmodule itself.\n\nThis library contains only one export, at `src/index.ts` (a function called\n`shell`), but you could import e.g. `import { test } from \"my-package/path/to/export\"` by exporting that identifier at `src/path/to/export/index.ts`.\n\n### React component library (using Next.js)\n\n`tsmodule create --react` creates a TS module which is also a Next app; pages are in `src/pages`, and components are in `src/components`. Tailwind, PostCSS, and `postcss-import` are all supported by default.\n\nCSS will be bundled from `src/components/index.css` and exported at `my-package/styles`, which the package.json `style` field also points to (for `postcss-import` support), so that components packages are modular.\n\n\n  ```json\n  {\n    \"style\": \"./dist/components/index.css\",\n    \"exports\": {\n      \".\": \"./dist/index.js\",\n      \"./*\": \"./dist/components/*/index.js\",\n      \"./styles\": \"./dist/components/index.css\",\n      \"./styles/*\": \"./dist/components/*/index.css\",\n      \"./package.json\": \"./package.json\"\n    },\n  }\n  ```\n\nTo use a component downstream, import the styles into the page, e.g.:\n\n```tsx\n// src/pages/_app.tsx\nimport \"my-package/styles\";\n```\n\nOr in CSS (resolved by `postcss-import` using `\"style\"` field in package.json):\n\n```css\n@import \"my-package\";\n```\n\nAnd render your component:\n\n```tsx\n// src/pages/test.tsx\nimport { MyComponent } from \"my-package\";\n\nexport default function TestPage() {\n  return (\n    \u003cMyComponent /\u003e\n  );\n}\n```\n\n## Footnotes\n\n### Module configuration\n\nAll packages built with `tsmodule build` are ES modules. `{ \"type\": \"module\" }`\nis forced to minimize ambiguity.\n\n`tsmodule build` also forces the following tsconfig.json values during the\ntype-check and declaration emit:\n\n```json\n{\n  \"rootDir\": \"src/\",\n  \"outDir\": \"dist/\",\n}\n```\n\n#### Index exports\n\nConditional exports in package.json are configured such that \"index\nexports\" are available at a subpath. For example:\n\n```\nsrc/a/b/c/index.ts\n```\n\nWill be available downstream via:\n\n```ts\nimport { c } from \"your-package/a/b/c\"\n```\n\n**Notes:**\n\n- Index exports are the only entry points available for import, are ones located\nat `src/**/index.ts(x?)`.\u003csup\u003e1\u003c/sup\u003e\n\n- The default package entry point for `your-package` is `src/index.ts`.\n\n\u003csub\u003e\u003csup\u003e1\u003c/sup\u003e This has no restriction on internal imports between files,\nwhich can import from each other freely, including at runtime.\nHowever, consumers of your package will only be able to import from index\nexports as shown.\u003csub\u003e\n\n#### Package.json export\n\nFor information on why the `\"./package.json\": \"./package.json\"` export is\nspecified, see [#1](https://github.com/tsmodule/tsmodule/issues/1#issuecomment-1065500448).\n\n## License\n\nMIT © [C. Lewis](https://ctjlewis.com)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftsmodule%2Ftsmodule","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftsmodule%2Ftsmodule","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftsmodule%2Ftsmodule/lists"}