Zwitterion
A web dev server that lets you import anything*
Install / Use
/learn @lastmjs/ZwitterionREADME
Zwitterion
A web dev server that lets you import anything*
* If by anything you mean: JavaScript ES2015+, TypeScript, JSON, JSX, TSX, AssemblyScript, Rust, C, C++, WebAssembly, and in the future anything that compiles to JavaScript or WebAssembly.
Zwitterion is designed to be an instant replacement for your current web development static file server.
Production deployments are also possible through the static build.
For example, you can write stuff like the following and it just works:
./index.html:
<!DOCTYPE html>
<html>
<head>
<script type="module" src="app.ts"></script>
</head>
<body>
This is the simplest developer experience I've ever had!
</body>
</html>
./app.ts:
import { getHelloWorld } from './hello-world.ts';
const helloWorld: string = getHelloWorld();
console.log(helloWorld);
./hello-world.ts:
export function getHelloWorld(): string {
return 'Why hello there world!';
}
Really, it just works.
Zwitterion lets you get back to the good old days of web development.
Just write your source code in any supported language and run it in the browser.
Also...Zwitterion is NOT a bundler. It eschews bundling for a simpler experience.
Current Features
- ES2015+
- TypeScript
- JSON
- JSX
- TSX
- AssemblyScript
- Rust (basic support)
- C (basic support)
- C++ (basic support)
- WebAssembly Text Format (Wat)
- WebAssembly (Wasm)
- Bare imports (
import * as stuff from 'library';instead ofimport * as stuff from '../node_modules/library/index.js';) - Single Page Application routing (by default the server returns
index.htmlon unhandled routes) - Static build for production deployment
Upcoming Features
- More robust Rust integration (i.e. automatic local Rust installation during npm installation)
- More robust C integration
- More robust C++ integration
- Import maps
- HTTP2 optimizations
Documentation
- Examples
- Installation and Basic Use
- Production Use
- Languages
- Command Line Options
- Special Considerations
- Under the Hood
Installation and Basic Use
Local Installation and Use
Install Zwitterion in the directory that you would like to serve files from:
npm install zwitterion
Run Zwitterion by accessing its executable directly from the terminal:
node_modules/.bin/zwitterion
or from an npm script:
{
...
"scripts": {
"start": "zwitterion"
}
...
}
Global Installation and Use
Install Zwitterion globally to use across projects:
npm install -g zwitterion
Run Zwitterion from the terminal:
zwitterion
or from an npm script:
{
...
"scripts": {
"start": "zwitterion"
}
...
}
Production Use
It is recommended to use Zwitterion in production by creating a static build of your project. A static build essentially runs all relevant files through Zwitterion, and copies those and all other files in your project to a dist directory. You can take this directory and upload it to a Content Delivery Network (CDN), or another static file hosting service.
You may also use a running Zwitterion server in production, but for performance and potential security reasons it is not recommended.
To create a static build, run Zwitterion with the --build-static option. You will probably need to add the application/javascript MIME type to your hosting provider for your TypeScript, AssemblyScript, Rust, Wasm, and Wat files.
From the terminal:
zwitterion --build-static
From an npm script:
{
...
"scripts": {
"build-static": "zwitterion --build-static"
}
...
}
The static build will be located in a directory called dist, in the same directory that you ran the --build-static command from.
Languages
JavaScript
JavaScript is the language of the web. You can learn more here.
Importing JavaScript ES2015+ is straightforward and works as expected. Simply use import and export statements without any modifications. It is recommended to use explicit file extensions:
./app.js:
import { helloWorld } from './hello-world.js';
console.log(helloWorld());
./hello-world.js:
export function helloWorld() {
return 'Hello world!';
}
JavaScript transpilation is done by the TypeScript compiler. By default, the TypeScript compiler's compilerOptions are set to the following:
{
"module": "ES2015",
"target": "ES2015"
}
You can override these options by creating a .json file with your own compilerOptions and telling Zwitterion where to locate it with the --tsc-options-file command line option. The available options can be found here. Options are specified as a JSON object. For example:
tsc-options.json:
{
"target": "ES5"
}
Tell Zwitterion where to locate it:
zwitterion --tsc-options-file tsc-options.json
TypeScript
TypeScript is a typed superset of JavaScript. You can learn more here.
Importing TypeScript is straightforward and works as expected. Simply use import and export statements without any modifications. It is recommended to use explicit file extensions:
./app.ts:
import { helloWorld } from './hello-world.ts';
console.log(helloWorld());
./hello-world.ts:
export function helloWorld(): string {
return 'Hello world!';
}
By default, the TypeScript compiler's compilerOptions are set to the following:
{
"module": "ES2015",
"target": "ES2015"
}
You can override these options by creating a .json file with your own compilerOptions and telling Zwitterion where to locate it with the --tsc-options-file command line option. The available options can be found here. Options are specified as a JSON object. For example:
tsc-options.json:
{
"target": "ES5"
}
Tell Zwitterion where to locate it:
zwitterion --tsc-options-file tsc-options.json
JSON
JSON is provided as a default export. It is recommended to use explicit file extensions:
./app.js:
import helloWorld from './hello-world.json';
console.log(helloWorld);
./hello-world.json:
{
"hello": "world"
}
JSX
Importing JSX is straightforward and works as expected. Simply use import and export statements without any modifications. It is recommended to use explicit file extensions:
./app.js:
import { helloWorldElement } from './hello-world.jsx';
ReactDOM.render(
helloWorldElement,
document.getElementById('root')
);
./hello-world.jsx:
export const hellowWorldElement = <h1>Hello, world!</h1>;
JSX transpilation is done by the TypeScript compiler. By default, the TypeScript compiler's compilerOptions are set to the following:
{
"module": "ES2015",
"target": "ES2015"
}
You can override these options by creating a .json file with your own compilerOptions and telling Zwitterion where to locate it with the --tsc-options-file command line option. The available options can be found here. Options are specified as a JSON object. For example:
tsc-options.json:
{
"target": "ES5"
}
Tell Zwitterion where to locate it:
zwitterion --tsc-options-file tsc-options.json
TSX
Importing TSX is straightforward and works as expected. Simply use import and export statements without any modifications. It is recommended to use explicit file extensions:
./app.js:
import { helloWorldElement } from './hello-world.tsx';
ReactDOM.render(
helloWorldElement,
document.getElementById('root')
);
./hello-world.tsx:
const helloWorld: string = 'Hello, world!';
export const hellowWorldElement = <h1>{ helloWorld }</h1>;
TSX transpilation is done by the TypeScript compiler. By default, the TypeScript compiler's compilerOptions are set to the following:
{
"module": "ES2015",
"target": "ES2015"
}
You can override these options by creating a .json file with your own compilerOptions and telling Zwitterion where to locate it with the --tsc-options-file command line option. The available options can be found here. Options are specified as a JSON object. For example:
tsc-options.json:
{
"target": "ES5"
}
Tell Zwitterion where to locate it:
zwitterion --tsc-options-file tsc-options.json
AssemblyScript
AssemblyScript is a new language that compiles a strict subset of TypeScript to WebAssembly. You can learn more about it in [The AssemblyScript Book](https://docs.assemblyscript.or
