-- Prompt Crafting with JSX --
Prxmpt is like "Tailwind for Prompt Engineering". It provides a set of utilities for formatting strings with JSX.
Prxmpt is designed for shaping the input to LLMs, and includes powerful elements such as <priority> for managing tokens. However, Prxmpt also provides both Markdown and HTML elements, making it perfect for formatting LLM outputs for end users as well.
- 📖 Readability - JSX gives us more control over whitespace, enabling more readable code.
- 🎛️ Control - With built-in props such as
hide
, we can easily control the text we display without ternaries. - 📦 Reusability - Prxmpt components take props just like normal JSX components, making them easy to reuse.
const text = (
<lined>
<h1>This is the first line.</h1>
<text hide={hideLine2}>Here's a second line.</text>
<empty />
<text>
This is a longer line, so we'll break the text tag.
We can even start another line here, and a space will be added.
</text>
</lined>
);
Result (hideLine2=false
)
# This is the first line.
Here's a second line.
This is a long line, so we'llbreak the text tag We can even start another line here, and a space will be added.
Result (hideLine2=true
)
# This is the first line.
This is a long line, so we'll break the text tag We can even start another line here, and a space will be added.
Compare this to an equivalent using template literals:
const text = `# This is the first line.${hideLine2 ? "\nHere's a second line." : ""}\n\nThis is a longer line, so by now we're off the page. We can even start another line here, but I wouldn't recommend it.`;
Automatic Mode
Prxmpt provides a base tsconfig.json
that you can extend:
{
"extends": "@autossey/prxmpt/tsconfig.json"
}
NOTE: Bun doesn't seem to detect Prxmpt correctly when using the "extends" method.
Alternatively, you can simply add the following fields to your tsconfig.json
:
{
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "@autossey/prxmpt",
"module": "NodeNext"
}
}
You should be able to use Prxmpt elements now, without importing:
export const MyComponent = () => (
<text>Hello, World!</text>
);
If using Prxmpt with React, add the following line at the top of each file that uses Prxmpt instead:
/** @jsxImportSource @autossey/prxmpt */ export const MyComponent = () => ( <text>Hello, World!</text> );
Classic Mode
To use Prxmpt in classic mode, you'll need to set the following fields in your tsconfig.json
:
{
"compilerOptions": {
"jsx": "react",
"jsxFactory": "Prxmpt.createElement",
"jsxFragmentFactory": "Prxmpt.Fragment"
}
}
Additionally, you'll need to import Prxmpt
in each file you use it:
import Prxmpt from "@autossey/prxmpt";
export const MyComponent = () => (
<text>Hello, World!</text>
);
Several examples are provided in the examples directory:
Element Usage Examples:
- kitchen sink (Showcases many elements)
- priority (A few examples of the
<priority>
element)
Setup Examples (TypeScript):
- bun
- bun (classic mode)
- Next.js
- swc
- swc (classic mode)
- ts-node
- ts-node (classic mode)
- tsc
- tsc (classic mode)
Setup Examples (JavaScript):
For examples of how to use specific elements, the tests show more usecases.
- Text Elements
- HTML Elements
- Serialization Elements
- Utility Elements
The following functions are also exported from Prxmpt:
<text>
Text is the base Prxmpt element. It returns its children as a string:
const string = <text>Hello, World!</text>;
Result
Hello, World!
Text can also be hidden with the hide
prop:
const string = <text>Hello<text hide>, World</hide>!</text>;
Result
Hello!
Props
Since <text>
is the base of most other elements, the props it provides can be used with most other elements.
Prxmpt treats children as an array of strings, which means <text>
can also provide several array functions for mapping, filtering, and joining children.
- hide
/**
* Prevent the Element from being rendered.
* @default false
*/
hide?: boolean;
- filter
/**
* A function to filter children.
* @default (node) => true
*/
filter?: (node: Prxmpt.Children, index: number, arr: Prxmpt.Children[]) => boolean;
- map
/**
* A function that maps each child to a new Element.
* @default (node) => Prxmpt.render(node)
*/
map?: (node: Prxmpt.Children, index: number, arr: Prxmpt.Children[]) => Prxmpt.JSX.Element;
- reverse
/**
* Reverse the order of the children.
*/
reverse?: boolean;
- join
/**
* An Element to insert between each child.
* @default ""
*/
join?: Prxmpt.Children;
- repeat
/**
* @default 1
*/
repeat?: number;
- trim
/**
* `true`: Trim whitespace from the beginning and end of the Element.
*
* `"start"`: Trim whitespace from the beginning of the Element.
*
* `"end"`: Trim whitespace from the end of the Element.
*
* @default false
*/
trim?: boolean | TrimSide;
- casing
/**
* Convert the Element to a given casing.
* @default undefined
*/
casing?: Casing;
- prefix
/**
* An Element to prepend to the element.
* @default ""
*/
prefix?: Prxmpt.Children;
- suffix
/**
* An Element to append to the element.
* @default ""
*/
suffix?: Prxmpt.Children;
- indent
/**
* Apply indentation to each line of the Element.
*
* If `true`, indentation is applied using 2 spaces.
*
* If a number is provided, that number of spaces is used.
*
* If `"\t"` is provided, a single tab character is used.
*
* @default false
*/
indent?: boolean | number | "\t";
- block
/**
* Append a newline to the end of the Element.
* @default false
*/
block?: boolean;
<empty>
The <empty>
element returns an empty string:
// ""
const string = <empty />;
<empty>
is often useful as a child of elements that join their children on some delimiter.
const string = (
<lined>
<text>Line 1</text>
<empty />
<text>Line 3</text>
</lined>
);
Result
Line 1
Line 2
<space>
The <space>
element returns a space:
// " "
const string = <space />;
<tab>
Props
- literal
/**
* If true, use a literal tab character. Otherwise, use spaces.
* @default false
*/
literal?: boolean;
- width
/**
* Number of characters per tab
* @default 1 if `literal` is true, otherwise 2
*/
width?: number;
// " "
const string = <tab width={4} />
<ellipsis>
const string = <ellipsis />;
Result
...
<na>
const string = <na />;
Result
n/a
<parens>
const string = <parens>Hello, World!</parens>;
Result
(Hello, World!)
<square>
const string = <square>Hello, World!</square>;
Result
[Hello, World!]
<curly>
const string = <curly>Hello, World!</curly>;
Result
{Hello, World!}
<angle>
const string = <angle>Hello, World!</angle>;
Result
<Hello, World!>
<sq>
const string = <sq>Hello, World!</sq>;
Result
'Hello, World!'
<dq>
const string = <dq>Hello, World!</dq>;
Result
"Hello, World!"
<bq>
const string = <bq>Hello, World!</bq>;
Result
`Hello, World!`
<tsq>
const string = <tsq>Hello, World!</tsq>;
Result
'''
Hello, World!
'''
<tdq>
const string = <tdq>Hello, World!</tdq>;
Result
"""
Hello, World!
"""
<tbq>
const tbq = <tbq>Hello, World!</tbq>;
Result
```
Hello, World!
```
<comment type="slash">
const slash = <comment type="slash">Hello, World!</comment>;
Result
// Hello, World!
<comment type="hash">
const hash = <comment type="hash">Hello, World!</comment>;
Result
# Hello, World!
<comment type="dash">
const dash = <comment type="dash">Hello, World!</comment>;
Result
-- Hello, World!
<comment type="html">
const html = <comment type="html">Hello, World!</comment>;
Result
<!-- Hello, World! -->
<state>
const state = <state>Hello, World!</state>;
Result
Hello, World.
<ask>
const ask = <ask>Hello, World!</ask>;
Result
Hello, World?
<exclaim>
const exclaim = <exclaim>Hello, World!</exclaim>;
Result
Hello, World!
<kv>
Props
- key
/**
* A key to render.
*/
key: Prxmpt.Children;
- keyCase
/**
* Case to apply to the key.
* @default undefined
*/
keyCase?: "upper" | "lower" | "capital" | "title";
- wrap
/**
* Override the default behavior for wrapping the value.
* @default undefined
*/
wrap?: boolean;
- noSpace
/**
* If true, do not add a space between the key and value.
* Only applies when not wrapping.
* @default false
*/
noSpace?: boolean;
const string = <kv key="Hello">World</kv>;
Result
Hello: World
When the children contain multiple lines, the value is rendered starting on a newline by default:
const worlds = (
<tdq join={"\n"}>
<text>World1</text>
<text>World2</text>
<text>World3</text>
</tdq>
);
const string = <kv key="Hello">{worlds}</kv>;
Result
Hello:
"""
World1
World2
World3
"""
HTML elements are built on top of the <tag>
element. Each html element has a boolean html
prop that is set to false by default. When html
is true, the element is rendered as HTML. Otherwise, the element is rendered as a Markdown equivalent.
Additionally, custom attributes can be set using the attributes
prop.
<tag>
Props
- name
/**
* Name of the tag.
*/
name: string;
- noIndent
/**
* @default false
*/
noIndent?: boolean;
- wrap
/**
* Defaults to true if the content contains a newline.
*/
wrap?: boolean;
const tag = <tag name="mytag">Hello, World!</tag>;
Result
<mytag>Hello, World!</mytag>
If no children are provided, the tag is rendered as a self-closing tag:
const tag = <tag name="mytag" />;
Result
<mytag />
<br />
// "\n"
const br = <br />;
const br = <br html />;
Result
<br />
<hr />
Props
- width
/**
* @default 3
*/
width?: number;
- char
/**
* @default "-"
*/
char?: "-" | "_" | "=" | "*";
const hr = <hr />;
Result
---
const hr = <hr />;
Result
<hr />
<a>
Props
- href
/**
* The URL of the link.
*/
href: string;
- title
/**
* A title for the link.
*/
title?: string;
const string = <a href="https://example.com" title="A Title">Hello, World!</a>;
Result
[Hello, World!](https://example.com "A Title")
const string = <a href="https://example.com" title="A Title" html>Hello, World!</a>;
Result
<a href="https://example.com" title="A Title">Hello, World!</a>
<img>
Props
- src
/**
* The URL of the image.
*/
href: string;
- title
/**
* A title for the image.
*/
title?: string;
const string = <img src="https://example.com" title="A Title">Hello, World!</img>;
Result
![Hello, World!](https://example.com "A Title")
const string = <img src="https://example.com" title="A Title" html>Hello, World!</img>;
Result
<img src="https://example.com" alt="Hello, World!" title="A Title" />
<h1>
const string = <h1>Hello, World!</h1>;
Result
# Hello, World!
const string = <h1 html>Hello, World!</h1>;
Result
<h1>Hello, World!</h1>
<h2>
const string = <h2>Hello, World!</h2>;
Result
## Hello, World!
const string = <h2 html>Hello, World!</h2>;
Result
<h2>Hello, World!</h2>
<h3>
const string = <h3>Hello, World!</h3>;
Result
### Hello, World!
const string = <h3 html>Hello, World!</h3>;
Result
<h3>Hello, World!</h3>
<h4>
const string = <h4>Hello, World!</h4>;
Result
#### Hello, World!
const string = <h4 html>Hello, World!</h4>;
Result
<h4>Hello, World!</h4>
<h5>
const string = <h5>Hello, World!</h5>;
Result
##### Hello, World!
const string = <h5 html>Hello, World!</h5>;
Result
<h5>Hello, World!</h5>
<h6>
const string = <h6>Hello, World!</h6>;
Result
###### Hello, World!
const string = <h6 html>Hello, World!</h6>;
Result
<h6>Hello, World!</h6>
<ol>
Props
- onlyMarkIfList
/**
* Only include markers if the list contains more than one item.
* @default false
*/
onlyMarkIfList?: boolean;
const string = (
<ol>
<text>Hello</text>
<text>World</text>
</ol>
);
Result
1. Hello
2. World
<ul>
Props
- onlyMarkIfList
/**
* Only include markers if the list contains more than one item.
* @default false
*/
onlyMarkIfList?: boolean;
const string = (
<ul>
<text>Hello</text>
<text>World</text>
</ul>
);
Result
- Hello
- World
<cl>
Props
- items
items: {
/**
* @default false
*/
checked?: boolean;
/**
* Content to render after the checkbox.
*/
content: Prxmpt.Children;
}[];
const string = (
<cl
items={[
{ content: "Hello" },
{ content: "World", checked: true },
]}
/>
);
Result
- [ ] Hello
- [x] World
<dl>
Props
- items
/**
* The items to render.
*/
items: Record<string, Prxmpt.Children>;
- termCase
/**
* Casing to apply to each key.
* @default undefined
*/
termCase?: "upper" | "lower" | "capital" | "title";
- space
/**
* Number of blank lined to insert between each item.
* @default 0
*/
space?: number;
- wrap
/**
* Override the default behavior for wrapping values.
* @default undefined
*/
wrap?: boolean;
const string = (
<dl
items={{
Hello: "World",
Foo: "Bar"
}}
/>
);
Result
Hello: World
Foo: Bar
<i>
Props
- char
/**
* @default "_"
*/
char?: "*" | "_";
const string = <i>Hello, World!</i>;
Result
_Hello, World!_
const string = <i html>Hello, World!</i>;
Result
<i>Hello, World!</i>
<b>
Props
- char
/**
* @default "*"
*/
char?: "*" | "_";
const string = <b>Hello, World!</b>;
Result
**Hello, World!**
const string = <b html>Hello, World!</b>;
Result
<b>Hello, World!</b>
<s>
const string = <s>Hello, World!</s>;
Result
~~Hello, World!~~
const string = <s html>Hello, World!</s>;
Result
<s>Hello, World!</s>
<code>
const string = <code>Hello, World!</code>;
Result
`Hello, World!`
const string = <code html>Hello, World!</code>;
Result
<code>Hello, World!</code>
<span>
When rendered as text, <span>
simply renders its children like <text>
:
const string = <span>Hello, World!</span>;
Result
Hello, World!
const string = <span html>Hello, World!</span>;
Result
<span>Hello, World!</span>
<p>
When rendered as text, the paragraph tag adds a newline at the end of the element:
const string = <p>Hello, World!</p>;
Result
Hello, World!
const string = <p html>Hello, World!</p>;
Result
<p>Hello, World!</p>
<blockquote>
const string = (
<blockquote join={"\n"}>
<text>Hello</text>
<empty />
<text>World!</text>
</blockquote>
);
Result
> Hello
>
> World!
const string = <blockquote html>Hello, World!</blockquote>;
Result
<blockquote>Hello, World!</blockquote>
<q>
Props
- type
/**
* @default "double"
*/
type?: "single" | "double" | "backtick";
The quote element returns a triple quote if the children contain a newline, otherwise it returns a single quote.
const string = <q>Hello, World!</q>;
Result
"Hello, World!"
const string = <q>Hello<br />World</q>;
Result
"""
Hello, World!
"""
const string = <q html>Hello, World!</q>;
Result
<q>Hello, World!</q>
<pre>
const string = <pre>Hello, World!</pre>;
Result
```
Hello, World!
```
const string = <pre html>Hello, World!</pre>;
Result
<pre>Hello, World!</pre>
<num>
Props
- add
/**
* Add a value to the number.
*/
add?: number;
- min
/**
* Minimum value. Applied after `add`.
*/
min?: number;
- max
/**
* Maximum value. Applied after `add`.
*/
max?: number;
- fixed
/**
* Number of decimal places.
*/
fixed?: number;
const string = <num fixed={2}>1</num>;
Result
1.00
const string = <num min={1}>0</num>;
Result
1
Props
- value
/**
* @default Date.now()
*/
value?: Date | string | number;
- dateFormat
/**
* @default "short"
*/
dateFormat?: "long" | "medium" | "short" | "full";
- timeFormat
/**
* @default "short"
*/
timeFormat?: "long" | "medium" | "short" | "full";
const string = <datetime />;
Result
September 23, 2023 at 5:17 PM
Props
- value
/**
* @default Date.now()
*/
value?: Date | string | number;
- format
/**
* @default "short"
*/
format?: "long" | "medium" | "short" | "full";
const string = <date />;
Result
September 23, 2023
Props
- value
/**
* @default Date.now()
*/
value?: Date | string | number;
- format
/**
* @default "short"
*/
format?: "long" | "medium" | "short" | "full";
const string = <time />;
Result
5:17 PM
Props
- value
/**
* @default Date.now()
*/
value?: Date | string | number;
const string = <year />
Result
2023
Props
- value
/**
* @default Date.now()
*/
value?: Date | string | number;
- format
/**
* @default "number"
*/
format?: "number" | "long" | "short" | "narrow";
const string = <month />
Result
8
const string = <month format="long" />
Result
September
const string = <month format="short" />
Result
Sep
const string = <month format="narrow" />
Result
S
Props
- value
/**
* @default Date.now()
*/
value?: Date | string | number;
- format
/**
* @default "number"
*/
format?: "number" | "long" | "short" | "narrow";
const string = <day />
Result
6
const string = <day format="long" />
Result
Saturday
const string = <day format="short" />
Result
Sat
const string = <day format="narrow" />
Result
S
Props
- value
/**
* @default Date.now()
*/
value?: Date | string | number;
- cycle
/**
* @default "12"
*/
cycle?: "12" | "24";
const string = <hour />
Result
5
const string = <hour cycle="24">
Result
17
Props
- value
/**
* @default Date.now()
*/
value?: Date | string | number;
const string = <minute />
Result
42
Props
- value
/**
* @default Date.now()
*/
value?: Date | string | number;
const string = <second />
Result
42
Props
- value
/**
* @default Date.now()
*/
value?: Date | string | number;
const string = <millisecond />
Result
999
Props
- value
/**
* The end of the duration.
* @default Date.now()
*/
value?: Date | string | number;
- since
/**
* The start of the duration.
*/
since: Date | string | number;
const string = <duration since={"September 2021"} />
Result
2 years
Props
- data
/**
* The data to stringify.
*/
data: NestedOptionalJSONValue;
- pretty
/**
* @default false
*/
pretty?: boolean;
const string = <json data={{ Hello: "World" }} pretty />;
Result
{
"Hello": "World"
}
Props
- data
/**
* The data to stringify.
*/
data: NestedOptionalJSONValue;
- noStartMarker
/**
* @default false
*/
noStartMarker?: boolean;
- sequenceIndent
/**
* @default false
*/
sequenceIndent?: boolean;
const string = <yaml data={{ hello: "world" }} />;
Result
---
hello: world
<upper>
const string = <upper>Hello, World!</upper>;
Result
HELLO, WORLD!
<lower>
const string = <lower>Hello, World!</lower>;
Result
hello, world!
<capital>
const string = <capital>hello, world!</capital>;
Result
Hello, world!
<title>
const string = <title>hello, world!</title>;
Result
Hello, World!
// "Hello, World!"
const string = <trim>Hello, World! </trim>;
Result
Hello, World!
Props
- with
/**
* A value to apply to both `prefix` and `suffix`.
*/
with: Prxmpt.Children;
const string = <frame with="--">Hello, World! </frame>;
Result
-- Hello, World! --
<lined>
const string = (
<lined>
<text>Hello</text>
<text>World!</text>
</lined>
);
Result
Hello
World!
<spaced>
const string = (
<spaced>
<text>Hello</text>
<text>World!</text>
</spaced>
);
Result
Hello World!
<csl>
Props
- noSpace
/**
* @default false
*/
noSpace?: boolean;
const string = (
<csl>
<text>hello</text>
<text>world</text>
</csl>
);
Result
hello, world
const string = (
<csl noSpace>
<text>hello</text>
<text>world</text>
</csl>
);
Result
hello,world
<union>
Props
- noSpace
/**
* @default false
*/
noSpace?: boolean;
const string = (
<union>
<text>hello</text>
<text>world</text>
</union>
);
Result
hello | world
const string = (
<union noSpace>
<text>hello</text>
<text>world</text>
</union>
);
Result
hello|world
Props
- divider
/**
* @default "---"
*/
divider?: string;
- frame
/**
* Whether add dividers before and after the body.
* @default false
*/
frame?: boolean;
const string = (
<sectioned>
<text>Hello</text>
<text>World!</text>
</sectioned>
);
Result
Hello
---
World!
Sets automatically adjust the separators used based on the number of children provided.
<and>
const string = (
<and>
<text>a</text>
</and>
);
Result
a
const string = (
<and>
<text>a</text>
<text>b</text>
</and>
);
Result
a and b
const string = (
<and>
<text>a</text>
<text>b</text>
<text>c</text>
</and>
);
Result
a, b, and c
<andor>
const string = (
<andor>
<text>a</text>
<text>b</text>
<text>c</text>
</andor>
);
Result
a, b, and/or c
<or>
const string = (
<or>
<text>a</text>
<text>b</text>
<text>c</text>
</or>
);
Result
a, b, or c
<nor>
const string = (
<nor>
<text>a</text>
<text>b</text>
<text>c</text>
</nor>
);
Result
a, b, nor c
The <cap>
element allows you to limit the length of a string by providing a splitter
function and a max
number of "units" to allow.
Props
- max
/**
* The maximum "units" to include.
* @default Infinity
*/
max?: number;
- splitter
/**
* A function that splits a string into "units".
* @default "chars"
*/
splitter?: "paragraphs" | "lines" | "spaces" | "words" | "commas" | "chars" | (string: string) => string[];
- ellipsis
/**
* A string to append to the end if the maximum is reached.
* This string is included in the maximum count.
* If `true`, "..." is used.
* @default undefined
*/
ellipsis?: string | true;
const string = <cap max={5}>Hello, World!</cap>;
Result
Hello
The <priority>
element is like a width-based CSS media query for strings.
Instead of providing a list of children, <priority>
expects a list of items, each of which can have a priority. Higher priorities are rendered first (like z-index
in CSS), and each item has a default priority of 0. Several strategies are provided as well for fine-tuning how items are prioritiezed.
Priority elements can also be nested, which enable extremely fine-grained control over which content is rendered. Several examples are provided in the priority example directory.
Props
- max
/**
* The maximum "units" to include.
* @default Infinity
*/
max?: number;
- counter
/**
* A function that returns the number of "units" in a string.
* @default (string: string) => string.length
*/
counter?: (string: string) => number;
- items
/**
* The items to render, in order of priority.
*/
items: (Prxmpt.Children | {
/**
* The priority of this item. Higher priority items are included first.
* @default 0
*/
p?: number;
/**
* The content to render.
*/
content: ((capacity: number) => Prxmpt.Children) | Prxmpt.Children;
})[];
- strategy
The strategy to use when prioritizing items.
If multiple strategies are provided, subsequent strategies are tried in order to break ties.
"priority"
:
Prioritize items by the provided priority.
Once the maximum is reached, continue to check if remaining items fit.
"order-asc"
:
Prioritize items by the order provided.
Once the maximum is reached, continue to check if remaining items fit.
"order-desc"
:
Prioritize items in reverse of the order provided.
Once the maximum is reached, continue to check if remaining items fit.
"size-asc"
:
Prioritize items in size order, smallest to largest.
Use if you want to include as many items as possible.
"size-desc"
:
Prioritized items in size order, largest to smallest.
Use if you want to include as few items as possible.
/**
* @default ["priority", "order-asc"]
*/
strategy?: PriorityStrategy | PriorityStrategy[];
- noSkip
/**
* If `true`, do not skip items after the maximum is reached.
* @default false
*/
noSkip?: boolean;
const string = (
<priority
max={15}
join={"\n"}
items={[{
p: 2
content: "Test 1"
}, {
// p: 0 is the default
content: "This is a a super long string that won't fit."
}, {
p: 1,
content: "Test 3"
}]} />
);
Result
Test 1
Test 3
import { createElement } from "@autossey/prxmpt";
const string = createElement("text", {}, "Hello, World!");
Result
Hello, World!
import { render } from "@autossey/prxmpt";
const string = render(
<text>Hello, World!</text>
);
Result
Hello, World!
Returns true
if the provided props object has a children
property.
import { hasChildren } from "@autossey/prxmpt";
if(hasChildren({ children: "Hello, World!" })) {
// ...
}
Returns true
if the provided value is a valid Prxmpt element child.
import { isChildren } from "@autossey/prxmpt";
if(isChildren("Hello, World!")) {
// ...
}
Split children
on separator
. If separator
is undefined
, no splitting occurs.
import { split } from "@autossey/prxmpt";
const children = (
<lined>
<text>Hello</text>
<text>World!</text>
</lined>
);
// ["Hello", "World!"]
const strings = split(children, "\n");
Split children
on "\n\n"
.
Split children
on "\n"
.
Split children
on whitespace.
Split children
on word boundaries.
Split children
on ","
.
Split children
on ""
.
- @swc/core: Super-fast alternative for babel
- as-typed-array: Make any value an array
- types-json: Type checking for JSON objects
- yaml: JavaScript parser and stringifier for YAML
- @autossey/eslint-config: A base for projects that use ESLint.
- @autossey/tsconfig: A collection of base TSConfigs for various types of projects.
- @jest/globals
- @swc/jest: Swc integration for jest
- @types/node: TypeScript definitions for Node.js
- eslint: An AST-based pattern checker for JavaScript.
- jest: Delightful JavaScript Testing.
- typescript: TypeScript is a language for application scale JavaScript development
MIT - The MIT License