Dune is an open-source, cross-platform, shell around the V8 engine, written in Rust and capable of running JavaScript (dah) and TypeScript code out of the box.
Developed completely for fun and experimentation.
Mac, Linux:
curl -fsSL https://raw.githubusercontent.com/aalykiot/dune/main/install.sh | sh
Windows (PowerShell)
irm https://raw.githubusercontent.com/aalykiot/dune/main/install.ps1 | iex
Otherwise you have to manually download and unzip the release build.
From Source:
Clone the repo and build it using Cargo.
git clone https://github.com/aalykiot/dune.git && cd ./dune && cargo build --release
Make sure to create a
.dunedirectory under your user.
A simple example.
import shortid from 'https://cdn.skypack.dev/shortid';
console.log(shortid()); //=> "lXN1aGba2"
Another example using the net module.
import net from 'net';
const server = net.createServer(async (socket) => {
console.log('Got new connection!');
await socket.write('Hello! 👋\n');
await socket.destroy();
});
await server.listen(3000, '127.0.0.1');
console.log('Server is listening on port 3000...');
JSX/TSX files are also supported for server side rendering.
import { h, Component } from 'https://esm.sh/preact@10.11.3';
import { render } from 'https://esm.sh/preact-render-to-string@5.2.6';
/** @jsx h */
// Classical components work.
class Fox extends Component {
render({ name }) {
return <span class="fox">{name}</span>;
}
}
// ... and so do pure functional components:
const Box = ({ type, children }) => (
{children}
);
let html = render(
<Box type="open">
<Fox name="Finn" />
</Box>
);
console.log(html);
For more examples look at the examples directory.
global: Reference to the global object.globalThis: Same as global.console: A subset of the WHATWG console.prompt: Shows the given message and waits for the user's input.TextEncoder / TextDecoder: WHATWG encoding API.setTimeout / setInterval / clearTimeout / clearInterval: DOM style timers.setImmediate / clearImmediate: Node.js like immediate timers.process: An object that provides info about the current dune process.structuredClone: Creates a deep clone of a given value.AbortController / AbortSignal: Allows you to communicate with a request and abort it.fetch: A wrapper around http.request (not fully compatible with WHATWG fetch).queueMicrotask: Queues a microtask to invoke a callback.import.meta.url: A string representation of the fully qualified module URL.import.meta.main: A flag that indicates if the current module is the main module.import.meta.resolve(specifier): A function that returns resolved specifier.argv: An array containing the command-line arguments passed when the dune process was launched.cwd(): Current working directory.env: An object containing the user environment.exit(code?): Exits the program with the given code.getActiveResourcesInfo(): An array of strings containing the types of the active resources that are currently keeping the event loop alive. 🚧memoryUsage(): An object describing the memory usage.nextTick(cb, ...args?): Adds callback to the "next tick queue".pid: PID of the process.platform: A string identifying the operating system platform.uptime(): A number describing the amount of time (in seconds) the process is running.version: The dune version.versions: An object listing the version strings of dune and its dependencies.binding(module): Exposes modules with bindings to Rust.kill(pid, signal?): Sends the signal to the process identified by pid.stdout: Points to system's stdout stream.stdin: Points to system's stdin stream.stderr: Points to system's stderr stream.uncaughtException: Emitted when an uncaught exception bubbles up to Dune.unhandledRejection: Emitted when a Promise is rejected with no handler.Signal events will be emitted when the Dune process receives a signal. Please refer to signal(7) for a listing of standard POSIX signal names.
This module also includes a
Syncmethod for every async operation available.
copyFile(src, dest): Copies src to dest.createReadStream(path, options?): Returns a new readable IO stream.createWriteStream(path, options?): Returns a new writable IO stream.open(path, mode?): Asynchronous file open.mkdir(path, options?): Creates a directory.readFile(path, options?): Reads the entire contents of a file.rmdir(path, options?): Deletes a directory (must be empty).readdir(path): Reads the contents of a directory.rm(path, options?): Removes files and directories.rename(from, to): Renames the file from oldPath to newPath.stat(path): Retrieves statistics for the file.watch(path, options?): Returns an async iterator that watches for changes over a path.writeFile(path, data, options?): Writes data to the file, replacing the file if it already exists.Data (to be written) must be of type String|Uint8Array.
fd: The numeric file descriptor.close(): Closes the file.read(buffer, offset?): Reads data from the file.stat(): Retrieves statistics for the file.write(data, offset?): Writes data to the file.createServer(connectionHandler?): Creates a new TCP server.createConnection(options): Creates unix socket connection to a remote host.connect(options): An alias of createConnection().TimeoutError: Custom error signalling a socket (read) timeout.net.Servernet.Server is a class extending
EventEmitterand implements@@asyncIterator.
listen(port, host?): Begin accepting connections on the specified port and host.accept(): Waits for a TCP client to connect and accepts the connection.address(): Returns the bound address.close(): Stops the server from accepting new connections and keeps existing connections.listening: Emitted when the server has been bound after calling server.listen.connection: Emitted when a new connection is made.close: Emitted when the server stops accepting new connections.error: Emitted when an error occurs.net.Socketnet.Socket is a class extending
EventEmitterand implements@@asyncIterator.
connect(options): Opens the connection for a given socket.setEncoding(encoding): Sets the encoding for the socket.setTimeout(timeout): Sets the socket's timeout threshold when reading.read(): Reads data out of the socket.write(data): Sends data on the socket.end(data?): Half-closes the socket. i.e., it sends a FIN packet.destroy(): Closes and discards the TCP socket stream.address(): Returns the bound address.remoteAddress: The string representation of the remote IP address.remotePort: The numeric representation of the remote port.bytesRead: The amount of received bytes.bytesWritten: The amount of bytes sent.connect: Emitted when a socket connection is successfully established.data: Emitted when data is received.end: Emitted when the other end of the socket sends a FIN packet.error: Emitted when an error occurs.close: Emitted once the socket is fully closed.timeout: Emitted if the socket times out from (read) inactivity.The HTTP package is inspired by Node.js' undici package.
METHODS: A list of the HTTP methods that are supported by the parser.STATUS_CODES: A collection of all the standard HTTP response status codes.request(url, options?): Performs an HTTP request.createServer(requestHandler?): Creates a new HTTP server.Details
const URL = 'http://localhost:3000/foo';
const { statusCode, headers, body } = await http.request(URL);
RequestOptions
method: (string) - Default: GETheaders: (object) - Default: nullbody: (string | Uint8Array | stream.Readable) - Default: nulltimeout: (number) - Default: 30000 (30 seconds) - Use 0 to disable it entirely.throwOnError: (boolean) - Default: false - Whether should throw an error upon receiving a 4xx or 5xx response.signal: (AbortSignal) - Default: null - Allows you to communicate with the request and abort it.Body Mixins
The body mixins are the most common way to format the response body.
text(): Produces a UTF-8 string representation of the body.json(): Formats the body using JSON parsing.http.Serverhttp.Server is a class extending
EventEmitterand implements@@asyncIterator.
listen(port, host?): Starts the HTTP server listening for connections.close(): Stops the server from accepting new connections.accept(): Waits for a client to connect and accepts the HTTP request.request: Emitted each time there is a request.close: Emitted when the server closes.clientError: Emitted when a client connection emits an 'error' event.http.ServerRequesthttp.ServerRequest implements
@@asyncIterator.
headers: The request headers object.httpVersion: The HTTP version sent by the client.method: The request method as a string.url: Request URL string.text(): Produces a UTF-8 string representation of the body.json(): Formats the body using JSON parsing.http.ServerResponsehttp.ServerResponse implements
stream.Writable.
write(data): This sends a chunk of the response body.end(data?): Signals that all of the response headers and body have been sent.writeHead(code, message?, headers?): Sends the response headers to the client.setHeader(name, value): Sets a single header value for implicit headers.getHeader(name): Reads out a header that's already been queued but not sent to the client.getHeaderNames(): Returns an array containing the unique names of the current outgoing headers.getHeaders(): Returns a copy of the current outgoing headers.hasHeader(name): Returns true if the header identified is currently set.removeHeader(name): Removes a header that's queued for implicit sending.headersSent: Boolean (read-only). True if headers were sent, false otherwise.socket: Reference to the underlying socket.finish: Emitted when the (full) response has been sent.Streams are very different from Node.js and are based on async-generators.
pipe(source, ...targets): An alias of pipeline().pipeline(source, ...targets): Pipes between streams while forwarding errors.compose(...targets): Combines two or more streams into a Duplex stream.timeOrigin: Specifies the millisecond timestamp at which the current process began.now(): Returns the millisecond timestamp, where 0 represents the start of the current process.All APIs exposed by this module execute synchronously.
sqlite.Databaseopen(): Opens the database specified in the constructor.loadExtension(path): Loads a shared library into the database connection.enableLoadExtension(flag): Enables or disables the loadExtension SQL function.exec(sql): SQL statements to be executed without returning any results.prepare(sql): Compiles a SQL statement into a prepared statement.close(): Closes the database connection.isOpen: Whether the database is currently open or not.To use an in-memory database, the path should be the special name
:memory:.
sqlite.Statementrun(...params?): Executes a prepared statement and returns the resulting changes.columns(): Used to retrieve information about the columns.all(...params?): Executes a prepared statement and returns all results.get(...params?): Returns the first result.setReadBigInts(flag): Enables or disables the use of BigInts when reading INTEGER fields.sourceSQL: The source SQL text of the prepared statement.expandedSQL: The source SQL text of the prepared statement with parameter placeholders replaced.test(description, [options], testFn): Registers a test with the default test runner.TestRunner: (Class) A main executor to run JavaScript and TypeScript tests.Details
Options
ignore: (boolean) - Default: false - Ignore test based on a runtime check.Custom Executors
You can attach tests to custom runners and run them manually.
```js import