postseed 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. postseed-0.1.0/LICENSE +21 -0
  2. postseed-0.1.0/PKG-INFO +79 -0
  3. postseed-0.1.0/README.md +52 -0
  4. postseed-0.1.0/pyproject.toml +44 -0
  5. postseed-0.1.0/setup.cfg +4 -0
  6. postseed-0.1.0/src/postseed/__init__.py +111 -0
  7. postseed-0.1.0/src/postseed/__main__.py +5 -0
  8. postseed-0.1.0/src/postseed/_engine/node_modules/jiti/LICENSE +21 -0
  9. postseed-0.1.0/src/postseed/_engine/node_modules/jiti/README.md +258 -0
  10. postseed-0.1.0/src/postseed/_engine/node_modules/jiti/dist/babel.cjs +257 -0
  11. postseed-0.1.0/src/postseed/_engine/node_modules/jiti/dist/jiti.cjs +1 -0
  12. postseed-0.1.0/src/postseed/_engine/node_modules/jiti/lib/jiti-cli.mjs +34 -0
  13. postseed-0.1.0/src/postseed/_engine/node_modules/jiti/lib/jiti-hooks.mjs +124 -0
  14. postseed-0.1.0/src/postseed/_engine/node_modules/jiti/lib/jiti-native.mjs +121 -0
  15. postseed-0.1.0/src/postseed/_engine/node_modules/jiti/lib/jiti-register.d.mts +1 -0
  16. postseed-0.1.0/src/postseed/_engine/node_modules/jiti/lib/jiti-register.mjs +4 -0
  17. postseed-0.1.0/src/postseed/_engine/node_modules/jiti/lib/jiti-static.mjs +23 -0
  18. postseed-0.1.0/src/postseed/_engine/node_modules/jiti/lib/jiti.cjs +30 -0
  19. postseed-0.1.0/src/postseed/_engine/node_modules/jiti/lib/jiti.d.cts +8 -0
  20. postseed-0.1.0/src/postseed/_engine/node_modules/jiti/lib/jiti.d.mts +8 -0
  21. postseed-0.1.0/src/postseed/_engine/node_modules/jiti/lib/jiti.mjs +29 -0
  22. postseed-0.1.0/src/postseed/_engine/node_modules/jiti/lib/types.d.ts +420 -0
  23. postseed-0.1.0/src/postseed/_engine/node_modules/jiti/package.json +146 -0
  24. postseed-0.1.0/src/postseed/_engine/package.json +1 -0
  25. postseed-0.1.0/src/postseed/_engine/postseed.mjs +503 -0
  26. postseed-0.1.0/src/postseed/cli.py +29 -0
  27. postseed-0.1.0/src/postseed/studio-dist/assets/TemplatesScreen-DbIyICkA.js +332 -0
  28. postseed-0.1.0/src/postseed/studio-dist/assets/index-BM0OsIyI.js +55 -0
  29. postseed-0.1.0/src/postseed/studio-dist/assets/index-Dqw83Nte.css +2 -0
  30. postseed-0.1.0/src/postseed/studio-dist/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
  31. postseed-0.1.0/src/postseed/studio-dist/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
  32. postseed-0.1.0/src/postseed/studio-dist/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
  33. postseed-0.1.0/src/postseed/studio-dist/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
  34. postseed-0.1.0/src/postseed/studio-dist/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
  35. postseed-0.1.0/src/postseed/studio-dist/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
  36. postseed-0.1.0/src/postseed/studio-dist/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
  37. postseed-0.1.0/src/postseed/studio-dist/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2 +0 -0
  38. postseed-0.1.0/src/postseed/studio-dist/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2 +0 -0
  39. postseed-0.1.0/src/postseed/studio-dist/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
  40. postseed-0.1.0/src/postseed/studio-dist/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
  41. postseed-0.1.0/src/postseed/studio-dist/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2 +0 -0
  42. postseed-0.1.0/src/postseed/studio-dist/favicon.svg +6 -0
  43. postseed-0.1.0/src/postseed/studio-dist/index.html +16 -0
  44. postseed-0.1.0/src/postseed.egg-info/PKG-INFO +79 -0
  45. postseed-0.1.0/src/postseed.egg-info/SOURCES.txt +47 -0
  46. postseed-0.1.0/src/postseed.egg-info/dependency_links.txt +1 -0
  47. postseed-0.1.0/src/postseed.egg-info/entry_points.txt +2 -0
  48. postseed-0.1.0/src/postseed.egg-info/top_level.txt +1 -0
  49. postseed-0.1.0/tests/test_postseed.py +102 -0
postseed-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Sagar Pinninti
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,79 @@
1
+ Metadata-Version: 2.4
2
+ Name: postseed
3
+ Version: 0.1.0
4
+ Summary: Realistic, relationship-correct seed data for PostgreSQL. Local-first and deterministic. Runs the Postseed CLI and Studio with Node.js.
5
+ Author: Sagar Pinninti
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/isagarpinninti/postseed
8
+ Project-URL: Documentation, https://github.com/isagarpinninti/postseed#readme
9
+ Project-URL: Issues, https://github.com/isagarpinninti/postseed/issues
10
+ Project-URL: Changelog, https://github.com/isagarpinninti/postseed/blob/main/CHANGELOG.md
11
+ Keywords: postgres,postgresql,seed,seed-data,fake-data,test-data,fixtures,faker,deterministic,database
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.8
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Database
21
+ Classifier: Topic :: Software Development :: Testing
22
+ Classifier: Operating System :: OS Independent
23
+ Requires-Python: >=3.8
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Dynamic: license-file
27
+
28
+ # postseed (Python)
29
+
30
+ [![PyPI](https://img.shields.io/pypi/v/postseed)](https://pypi.org/project/postseed/)
31
+ [![CI](https://github.com/isagarpinninti/postseed/actions/workflows/ci.yml/badge.svg)](https://github.com/isagarpinninti/postseed/actions/workflows/ci.yml)
32
+ [![License: MIT](https://img.shields.io/badge/license-MIT-black.svg)](https://github.com/isagarpinninti/postseed/blob/main/LICENSE)
33
+
34
+ **Realistic Postgres seed data. In seconds.** Postseed generates seed data that respects your foreign keys, enums and uniqueness, never leaves your machine, and is deterministic: the same schema, seed and version give byte-identical output.
35
+
36
+ This package bundles the [Postseed](https://github.com/isagarpinninti/postseed) engine and runs it with **Node.js 20 or newer** (it must be on your `PATH`, or set `POSTSEED_NODE`). Nothing else to install.
37
+
38
+ ```bash
39
+ pip install postseed
40
+ postseed # opens Studio, the local web app, on 127.0.0.1
41
+ ```
42
+
43
+ ## Command line
44
+
45
+ ```bash
46
+ postseed generate --schema schema.sql --rows 50 --seed 42 --out seed.sql
47
+ postseed insert --url "$DATABASE_URL" --dry-run # validate against your database, then roll back
48
+ postseed insert --url "$DATABASE_URL" --yes # really insert, in one transaction
49
+ ```
50
+
51
+ See the [documentation](https://github.com/isagarpinninti/postseed#readme) for every option.
52
+
53
+ ## From Python
54
+
55
+ ```python
56
+ import postseed
57
+
58
+ sql = postseed.generate(
59
+ """
60
+ CREATE TABLE users (id serial PRIMARY KEY, email text UNIQUE NOT NULL);
61
+ CREATE TABLE posts (id serial PRIMARY KEY, user_id int NOT NULL REFERENCES users(id), title text);
62
+ """,
63
+ rows=25,
64
+ seed=42,
65
+ )
66
+ # `sql` is a transactional script: every post points at a real user, every email is unique.
67
+ ```
68
+
69
+ `generate(schema_sql, *, rows=50, seed=42, format="sql", tables=None, table_rows=None, null_ratio=None, now=None)`
70
+ returns the text (`format` is `"sql"` or `"json"`) and raises `postseed.PostseedError` with the engine's message
71
+ if it cannot. The same arguments always return the same text.
72
+
73
+ `postseed.run(args, input=None)` runs any CLI command and returns a `subprocess.CompletedProcess`.
74
+
75
+ ## Notes
76
+
77
+ - Python 3.8 or newer. The package is pure Python plus a bundled JavaScript engine, so there is one wheel for every platform.
78
+ - It is the same engine as the `postseed` npm package and the `postseed` gem, so output is identical across all three.
79
+ - MIT licensed.
@@ -0,0 +1,52 @@
1
+ # postseed (Python)
2
+
3
+ [![PyPI](https://img.shields.io/pypi/v/postseed)](https://pypi.org/project/postseed/)
4
+ [![CI](https://github.com/isagarpinninti/postseed/actions/workflows/ci.yml/badge.svg)](https://github.com/isagarpinninti/postseed/actions/workflows/ci.yml)
5
+ [![License: MIT](https://img.shields.io/badge/license-MIT-black.svg)](https://github.com/isagarpinninti/postseed/blob/main/LICENSE)
6
+
7
+ **Realistic Postgres seed data. In seconds.** Postseed generates seed data that respects your foreign keys, enums and uniqueness, never leaves your machine, and is deterministic: the same schema, seed and version give byte-identical output.
8
+
9
+ This package bundles the [Postseed](https://github.com/isagarpinninti/postseed) engine and runs it with **Node.js 20 or newer** (it must be on your `PATH`, or set `POSTSEED_NODE`). Nothing else to install.
10
+
11
+ ```bash
12
+ pip install postseed
13
+ postseed # opens Studio, the local web app, on 127.0.0.1
14
+ ```
15
+
16
+ ## Command line
17
+
18
+ ```bash
19
+ postseed generate --schema schema.sql --rows 50 --seed 42 --out seed.sql
20
+ postseed insert --url "$DATABASE_URL" --dry-run # validate against your database, then roll back
21
+ postseed insert --url "$DATABASE_URL" --yes # really insert, in one transaction
22
+ ```
23
+
24
+ See the [documentation](https://github.com/isagarpinninti/postseed#readme) for every option.
25
+
26
+ ## From Python
27
+
28
+ ```python
29
+ import postseed
30
+
31
+ sql = postseed.generate(
32
+ """
33
+ CREATE TABLE users (id serial PRIMARY KEY, email text UNIQUE NOT NULL);
34
+ CREATE TABLE posts (id serial PRIMARY KEY, user_id int NOT NULL REFERENCES users(id), title text);
35
+ """,
36
+ rows=25,
37
+ seed=42,
38
+ )
39
+ # `sql` is a transactional script: every post points at a real user, every email is unique.
40
+ ```
41
+
42
+ `generate(schema_sql, *, rows=50, seed=42, format="sql", tables=None, table_rows=None, null_ratio=None, now=None)`
43
+ returns the text (`format` is `"sql"` or `"json"`) and raises `postseed.PostseedError` with the engine's message
44
+ if it cannot. The same arguments always return the same text.
45
+
46
+ `postseed.run(args, input=None)` runs any CLI command and returns a `subprocess.CompletedProcess`.
47
+
48
+ ## Notes
49
+
50
+ - Python 3.8 or newer. The package is pure Python plus a bundled JavaScript engine, so there is one wheel for every platform.
51
+ - It is the same engine as the `postseed` npm package and the `postseed` gem, so output is identical across all three.
52
+ - MIT licensed.
@@ -0,0 +1,44 @@
1
+ [build-system]
2
+ requires = ["setuptools>=64"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "postseed"
7
+ version = "0.1.0"
8
+ description = "Realistic, relationship-correct seed data for PostgreSQL. Local-first and deterministic. Runs the Postseed CLI and Studio with Node.js."
9
+ readme = "README.md"
10
+ license = { text = "MIT" }
11
+ requires-python = ">=3.8"
12
+ authors = [{ name = "Sagar Pinninti" }]
13
+ keywords = ["postgres", "postgresql", "seed", "seed-data", "fake-data", "test-data", "fixtures", "faker", "deterministic", "database"]
14
+ classifiers = [
15
+ "License :: OSI Approved :: MIT License",
16
+ "Programming Language :: Python :: 3",
17
+ "Programming Language :: Python :: 3.8",
18
+ "Programming Language :: Python :: 3.9",
19
+ "Programming Language :: Python :: 3.10",
20
+ "Programming Language :: Python :: 3.11",
21
+ "Programming Language :: Python :: 3.12",
22
+ "Programming Language :: Python :: 3.13",
23
+ "Topic :: Database",
24
+ "Topic :: Software Development :: Testing",
25
+ "Operating System :: OS Independent",
26
+ ]
27
+
28
+ [project.urls]
29
+ Homepage = "https://github.com/isagarpinninti/postseed"
30
+ Documentation = "https://github.com/isagarpinninti/postseed#readme"
31
+ Issues = "https://github.com/isagarpinninti/postseed/issues"
32
+ Changelog = "https://github.com/isagarpinninti/postseed/blob/main/CHANGELOG.md"
33
+
34
+ [project.scripts]
35
+ postseed = "postseed.cli:main"
36
+
37
+ [tool.setuptools]
38
+ package-dir = { "" = "src" }
39
+
40
+ [tool.setuptools.packages.find]
41
+ where = ["src"]
42
+
43
+ [tool.setuptools.package-data]
44
+ postseed = ["_engine/**/*", "studio-dist/**/*"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,111 @@
1
+ """Postseed for Python: realistic, relationship-correct seed data for PostgreSQL.
2
+
3
+ This package carries the same engine as the ``postseed`` npm package and runs it with Node.js 20 or newer.
4
+ Use the ``postseed`` command, or call :func:`generate` to get seed SQL for a schema from Python.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import json
10
+ import os
11
+ import shutil
12
+ import subprocess
13
+ import sys
14
+ from pathlib import Path
15
+ from typing import Dict, List, Mapping, Optional, Sequence
16
+
17
+ __all__ = ["__version__", "PostseedError", "NodeNotFoundError", "find_node", "run", "generate"]
18
+ __version__ = "0.1.0"
19
+
20
+ MIN_NODE = 20
21
+ ENGINE = Path(__file__).resolve().parent / "_engine" / "postseed.mjs"
22
+
23
+
24
+ class PostseedError(RuntimeError):
25
+ """The Postseed engine reported an error."""
26
+
27
+
28
+ class NodeNotFoundError(PostseedError):
29
+ """Node.js 20 or newer is required and was not found."""
30
+
31
+
32
+ def find_node() -> str:
33
+ """Path of a Node.js 20+ executable. Set POSTSEED_NODE to choose one explicitly."""
34
+ candidate = os.environ.get("POSTSEED_NODE") or shutil.which("node") or shutil.which("nodejs")
35
+ if not candidate:
36
+ raise NodeNotFoundError(
37
+ "Postseed needs Node.js %d or newer, and none was found on your PATH. "
38
+ "Install it from https://nodejs.org (or set POSTSEED_NODE to the node executable)." % MIN_NODE
39
+ )
40
+ try:
41
+ out = subprocess.run([candidate, "--version"], capture_output=True, text=True, timeout=15).stdout.strip()
42
+ major = int(out.lstrip("v").split(".")[0])
43
+ except (OSError, ValueError, subprocess.SubprocessError) as exc:
44
+ raise NodeNotFoundError(
45
+ "Could not run Node.js at %s (%s). Postseed needs Node.js %d or newer; "
46
+ "install it from https://nodejs.org or fix POSTSEED_NODE." % (candidate, exc, MIN_NODE)
47
+ ) from exc
48
+ if major < MIN_NODE:
49
+ raise NodeNotFoundError("Postseed needs Node.js %d or newer; found %s at %s." % (MIN_NODE, out, candidate))
50
+ return candidate
51
+
52
+
53
+ def _command(args: Sequence[str]) -> List[str]:
54
+ if not ENGINE.exists():
55
+ raise PostseedError("The bundled engine is missing (%s). Reinstall the postseed package." % ENGINE)
56
+ return [find_node(), str(ENGINE), *args]
57
+
58
+
59
+ def run(
60
+ args: Sequence[str],
61
+ *,
62
+ input: Optional[str] = None,
63
+ cwd: Optional[str] = None,
64
+ env: Optional[Mapping[str, str]] = None,
65
+ ) -> "subprocess.CompletedProcess[str]":
66
+ """Run the Postseed CLI and capture its output. Does not raise on a non-zero exit."""
67
+ return subprocess.run(
68
+ _command(args),
69
+ input=input,
70
+ capture_output=True,
71
+ text=True,
72
+ encoding="utf-8",
73
+ cwd=cwd,
74
+ env={**os.environ, **env} if env else None,
75
+ )
76
+
77
+
78
+ def generate(
79
+ schema_sql: str,
80
+ *,
81
+ rows: int = 50,
82
+ seed: int = 42,
83
+ format: str = "sql",
84
+ tables: Optional[Sequence[str]] = None,
85
+ table_rows: Optional[Mapping[str, int]] = None,
86
+ null_ratio: Optional[float] = None,
87
+ now: Optional[str] = None,
88
+ ) -> str:
89
+ """Generate seed data for a ``CREATE TABLE`` script and return it as text.
90
+
91
+ ``format`` is ``"sql"`` or ``"json"`` (CSV writes several files; use the CLI with ``--out``).
92
+ The same schema, seed and Postseed version always return identical text. Raises
93
+ :class:`PostseedError` with the engine's message if generation fails.
94
+ """
95
+ if format not in ("sql", "json"):
96
+ raise ValueError('format must be "sql" or "json" (use the CLI for csv)')
97
+ args = ["generate", "--schema", "-", "--rows", str(int(rows)), "--seed", str(int(seed)), "--format", format]
98
+ if tables:
99
+ args += ["--tables", ",".join(tables)]
100
+ if table_rows:
101
+ args += ["--table-rows", ",".join("%s=%d" % (k, v) for k, v in table_rows.items())]
102
+ if null_ratio is not None:
103
+ args += ["--null-ratio", str(null_ratio)]
104
+ if now:
105
+ args += ["--now", now]
106
+ done = run(args, input=schema_sql)
107
+ if done.returncode != 0:
108
+ raise PostseedError((done.stderr or done.stdout).strip() or "postseed exited with %d" % done.returncode)
109
+ if format == "json":
110
+ json.loads(done.stdout) # fail loudly if the output is not valid JSON
111
+ return done.stdout
@@ -0,0 +1,5 @@
1
+ import sys
2
+
3
+ from .cli import main
4
+
5
+ sys.exit(main())
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) Pooya Parsa <pooya@pi0.io>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,258 @@
1
+ # jiti
2
+
3
+ <!-- automd:badges color=F0DB4F bundlephobia -->
4
+
5
+ [![npm version](https://img.shields.io/npm/v/jiti?color=F0DB4F)](https://npmjs.com/package/jiti)
6
+ [![npm downloads](https://img.shields.io/npm/dm/jiti?color=F0DB4F)](https://npmjs.com/package/jiti)
7
+ [![bundle size](https://img.shields.io/bundlephobia/minzip/jiti?color=F0DB4F)](https://bundlephobia.com/package/jiti)
8
+
9
+ <!-- /automd -->
10
+
11
+ > This is the active development branch. Check out [jiti/v1](https://github.com/unjs/jiti/tree/v1) for legacy v1 docs and code.
12
+
13
+ ## 🌟 Used in
14
+
15
+ [Docusaurus](https://docusaurus.io/), [ESLint](https://github.com/eslint/eslint), [FormKit](https://formkit.com/), [Histoire](https://histoire.dev/), [Knip](https://knip.dev/), [Nitro](https://nitro.unjs.io/), [Nuxt](https://nuxt.com/), [PostCSS loader](https://github.com/webpack-contrib/postcss-loader), [Rsbuild](https://rsbuild.dev/), [Size Limit](https://github.com/ai/size-limit), [Slidev](https://sli.dev/), [Tailwindcss](https://tailwindcss.com/), [Tokenami](https://github.com/tokenami/tokenami), [UnoCSS](https://unocss.dev/), [WXT](https://wxt.dev/), [Winglang](https://www.winglang.io/), [Graphql code generator](https://the-guild.dev/graphql/codegen), [Lingui](https://lingui.dev/), [Scaffdog](https://scaff.dog/), [Storybook](https://storybook.js.org), [...UnJS ecosystem](https://unjs.io/), [...60M+ npm monthly downloads](https://npm.chart.dev/jiti), [...6M+ public repositories](https://github.com/unjs/jiti/network/dependents).
16
+
17
+ ## ✅ Features
18
+
19
+ - Seamless TypeScript and ESM syntax support for Node.js
20
+ - Seamless interoperability between ESM and CommonJS
21
+ - Asynchronous API to replace `import()`
22
+ - Synchronous API to replace `require()` (deprecated)
23
+ - Super slim and zero dependency
24
+ - Custom resolve aliases
25
+ - Smart syntax detection to avoid extra transforms
26
+ - Node.js native `require.cache` integration
27
+ - Filesystem transpile with hard disk caches
28
+ - ESM Loader support
29
+ - JSX support (opt-in)
30
+
31
+ > [!IMPORTANT]
32
+ > To enhance compatibility, jiti `>=2.1` enabled [`interopDefault`](#interopdefault) using a new Proxy method. If you migrated to `2.0.0` earlier, this might have caused behavior changes. In case of any issues during the upgrade, please [report](https://github.com/unjs/jiti/issues) so we can investigate to solve them. 🙏🏼
33
+
34
+ ## 💡 Usage
35
+
36
+ ### CLI
37
+
38
+ You can use `jiti` CLI to quickly run any script with TypeScript and native ESM support!
39
+
40
+ ```bash
41
+ npx jiti ./index.ts
42
+ ```
43
+
44
+ ### Programmatic
45
+
46
+ Initialize a jiti instance:
47
+
48
+ ```js
49
+ // ESM
50
+ import { createJiti } from "jiti";
51
+ const jiti = createJiti(import.meta.url);
52
+
53
+ // CommonJS (deprecated)
54
+ const { createJiti } = require("jiti");
55
+ const jiti = createJiti(__filename);
56
+ ```
57
+
58
+ Import (async) and resolve with ESM compatibility:
59
+
60
+ ```js
61
+ // jiti.import(id) is similar to import(id)
62
+ const mod = await jiti.import("./path/to/file.ts");
63
+
64
+ // jiti.esmResolve(id) is similar to import.meta.resolve(id)
65
+ const resolvedPath = jiti.esmResolve("./src");
66
+ ```
67
+
68
+ If you need the default export of module, you can use `jiti.import(id, { default: true })` as shortcut to `mod?.default ?? mod`.
69
+
70
+ ```js
71
+ // shortcut to mod?.default ?? mod
72
+ const modDefault = await jiti.import("./path/to/file.ts", { default: true });
73
+ ```
74
+
75
+ CommonJS (sync & deprecated):
76
+
77
+ ```js
78
+ // jiti() is similar to require(id)
79
+ const mod = jiti("./path/to/file.ts");
80
+
81
+ // jiti.resolve() is similar to require.resolve(id)
82
+ const resolvedPath = jiti.resolve("./src");
83
+ ```
84
+
85
+ You can also pass options as the second argument:
86
+
87
+ ```js
88
+ const jiti = createJiti(import.meta.url, { debug: true });
89
+ ```
90
+
91
+ ### Register global ESM loader
92
+
93
+ You can globally register jiti using [global hooks](https://nodejs.org/api/module.html#initialize). (Important: Requires Node.js > 20)
94
+
95
+ ```js
96
+ import "jiti/register";
97
+ ```
98
+
99
+ Or:
100
+
101
+ ```bash
102
+ node --import jiti/register index.ts
103
+ ```
104
+
105
+ ## 🎈 `jiti/native`
106
+
107
+ You can alias `jiti` to `jiti/native` to directly depend on runtime's [`import.meta.resolve`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import.meta/resolve) and dynamic [`import()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import) support. This allows easing up the ecosystem transition to runtime native support by giving the same API of jiti.
108
+
109
+ ## ⚙️ Options
110
+
111
+ ### `debug`
112
+
113
+ - Type: Boolean
114
+ - Default: `false`
115
+ - Environment variable: `JITI_DEBUG`
116
+
117
+ Enable verbose logging. You can use `JITI_DEBUG=1 <your command>` to enable it.
118
+
119
+ ### `fsCache`
120
+
121
+ - Type: Boolean | String
122
+ - Default: `true`
123
+ - Environment variable: `JITI_FS_CACHE`
124
+
125
+ Filesystem source cache (enabled by default)
126
+
127
+ By default (when is `true`), jiti uses `node_modules/.cache/jiti` (if exists) or `{TMP_DIR}/jiti`.
128
+
129
+ **Note:** It is recommended that this option be enabled for better performance.
130
+
131
+ ### `rebuildFsCache`
132
+
133
+ - Type: Boolean
134
+ - Default: `false`
135
+ - Environment variable: `JITI_REBUILD_FS_CACHE`
136
+
137
+ Rebuild filesystem source cache created by `fsCache`.
138
+
139
+ ### `moduleCache`
140
+
141
+ - Type: String
142
+ - Default: `true`
143
+ - Environment variable: `JITI_MODULE_CACHE`
144
+
145
+ Runtime module cache (enabled by default).
146
+
147
+ Disabling allows editing code and importing the same module multiple times.
148
+
149
+ When enabled, jiti integrates with Node.js native CommonJS cache-store.
150
+
151
+ ### `transform`
152
+
153
+ - Type: Function
154
+ - Default: Babel (lazy loaded)
155
+
156
+ Transform function. See [src/babel](./src/babel.ts) for more details
157
+
158
+ ### `sourceMaps`
159
+
160
+ - Type: Boolean
161
+ - Default `false`
162
+ - Environment variable: `JITI_SOURCE_MAPS`
163
+
164
+ Add inline source map to transformed source for better debugging.
165
+
166
+ ### `interopDefault`
167
+
168
+ - Type: Boolean
169
+ - Default: `true`
170
+ - Environment variable: `JITI_INTEROP_DEFAULT`
171
+
172
+ Jiti combines module exports with the `default` export using an internal Proxy to improve compatibility with mixed CJS/ESM usage. You can check the current implementation [here](https://github.com/unjs/jiti/blob/main/src/utils.ts#L105).
173
+
174
+ > [!WARNING]
175
+ > This option wraps **all imported modules** in a Proxy, which adds ~25-50ns overhead per property access. For performance-critical hot paths where you access module exports very frequently, consider setting `interopDefault: false` or `JITI_INTEROP_DEFAULT=false`.
176
+
177
+ ### `alias`
178
+
179
+ - Type: Object
180
+ - Default: -
181
+ - Environment variable: `JITI_ALIAS`
182
+
183
+ You can also pass an object to the environment variable for inline config. Example: `JITI_ALIAS='{"~/*": "./src/*"}' jiti ...`.
184
+
185
+ Custom alias map used to resolve IDs.
186
+
187
+ ### `tsconfigPaths`
188
+
189
+ - Type: Boolean | String
190
+ - Default: `false`
191
+ - Environment variable: `JITI_TSCONFIG_PATHS`
192
+
193
+ Enable TypeScript [`paths`](https://www.typescriptlang.org/tsconfig/#paths) resolution using [`get-tsconfig`](https://github.com/privatenumber/get-tsconfig).
194
+
195
+ - `true`: Auto-discover `tsconfig.json` by walking up from the jiti instance's parent path.
196
+ - `string`: Explicit path to a `tsconfig.json` file.
197
+ - `false` (default): Disabled.
198
+
199
+ ### `nativeModules`
200
+
201
+ - Type: Array
202
+ - Default: ['typescript']
203
+ - Environment variable: `JITI_NATIVE_MODULES`
204
+
205
+ List of modules (within `node_modules`) to always use native `require()` for them.
206
+
207
+ ### `transformModules`
208
+
209
+ - Type: Array
210
+ - Default: []
211
+ - Environment variable: `JITI_TRANSFORM_MODULES`
212
+
213
+ List of modules (within `node_modules`) to transform them regardless of syntax.
214
+
215
+ ### `importMeta`
216
+
217
+ Parent module's [`import.meta`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import.meta) context to use for ESM resolution. (only used for `jiti/native` import).
218
+
219
+ ### `tryNative`
220
+
221
+ - Type: Boolean
222
+ - Default: Enabled if bun is detected
223
+ - Environment variable: `JITI_TRY_NATIVE`
224
+
225
+ Try to use native require and import without jiti transformations first.
226
+
227
+ ### `jsx`
228
+
229
+ - Type: Boolean | {options}
230
+ - Default: `false`
231
+ - Environment Variable: `JITI_JSX`
232
+
233
+ Enable JSX support using [`@babel/plugin-transform-react-jsx`](https://babeljs.io/docs/babel-plugin-transform-react-jsx).
234
+
235
+ See [`test/fixtures/jsx`](./test/fixtures/jsx) for framework integration examples.
236
+
237
+ ## Development
238
+
239
+ - Clone this repository
240
+ - Enable [Corepack](https://github.com/nodejs/corepack) using `corepack enable`
241
+ - Install dependencies using `pnpm install`
242
+ - Run `pnpm dev`
243
+ - Run `pnpm jiti ./test/path/to/file.ts`
244
+
245
+ ## License
246
+
247
+ <!-- automd:contributors license=MIT author="pi0" -->
248
+
249
+ Published under the [MIT](https://github.com/unjs/jiti/blob/main/LICENSE) license.
250
+ Made by [@pi0](https://github.com/pi0) and [community](https://github.com/unjs/jiti/graphs/contributors) 💛
251
+ <br><br>
252
+ <a href="https://github.com/unjs/jiti/graphs/contributors">
253
+ <img src="https://contrib.rocks/image?repo=unjs/jiti" />
254
+ </a>
255
+
256
+ <!-- /automd -->
257
+
258
+ <!-- automd:with-automd -->