Getting Started
1.1 Introduction to Dovetail
Section titled “1.1 Introduction to Dovetail”What is Dovetail?
Section titled “What is Dovetail?”Dovetail is a new high-level programming language designed for writing business-logic heavy applications. It compiles to WebAssembly (specifically WasmGC), prioritizing fast compilation and great tooling over raw runtime performance.
Dovetail is:
- Expression-based - Everything is an expression that returns a value
- Strongly typed - A powerful type system catches errors at compile time
- Layout-sensitive - Uses indentation instead of curly braces and semicolons
- Functional-first - Encourages immutability and pure functions, while supporting imperative and object-oriented styles
- Garbage collected - Memory management is handled automatically
- Async-first - Built-in async/await with elegant error propagation
- No exceptions - Errors are values using
ResultandOptiontypes with railway-oriented programming
Why Another Language?
Section titled “Why Another Language?”Rust is a modern language for system-level programming, written from the ground up with modern concepts and a new ecosystem. It didn’t inherit old baggage from VMs or C/C++.
But we don’t have such a language for high-level programming.
TypeScript - A great language with modern concepts, but it’s based on JavaScript with the JavaScript ecosystem and a lot of baggage:
- Both async and callbacks
- Exceptions
- Nulls
- Inconsistency across the ecosystem (typed/untyped libraries)
- No ad-hoc polymorphism (traits, typeclasses)
Python - Popular but problematic for large codebases:
- Exceptions
- Nulls
- Untyped by default
- Both async and sync APIs
- Inconsistency in the ecosystem (is it typed or not? are all dependencies typed?)
- No ad-hoc polymorphism
Java - Mature but carrying decades of baggage:
- No async/await
- Type erasure
- Nulls
- Exceptions
- No standard across tools (formatter, build tool)
- No tuples
- No ad-hoc polymorphism
Kotlin - Modern features on top of Java, but still inherits Java’s baggage:
- JVM type erasure
- Exceptions
- Null safety is incomplete - the JVM isn’t null-safe, so you can encounter nulls at runtime from Java interop
- Standard library split between Kotlin and Java APIs
- No ad-hoc polymorphism
Scala - Powerful type system but with significant drawbacks:
- Inherits Java/JVM baggage
- Slow compilation times
- High learning curve
- Null safety is incomplete - JVM interop can introduce nulls at runtime
- Has ad-hoc polymorphism (implicits/givens), but at the cost of compilation performance and complexity
Go - Simple and fast to compile, but a limited type system:
- No sum types (discriminated unions)
- Limited generics (added recently, still maturing)
- Nulls (nil pointers)
- No async/await and no way to extend the language with custom coroutines
- Interfaces provide basic ad-hoc polymorphism, but more limited than traits (no associated types, can’t extend types you don’t own)
C# - Modern features but carrying .NET legacy:
- Standard library supports multiple models for backward compatibility
- Nullable reference types are opt-in and incomplete
- Exceptions
- No ad-hoc polymorphism
Rust - Amazing but low-level:
- No garbage collection
- Not optimized for compile times
- Steep learning curve for business logic developers
What is ecosystem baggage?
When we say “ecosystem baggage,” we mean:
- Legacy constructs in the language that exist for backward compatibility
- Standard libraries supporting multiple patterns (sync/async, exceptions/results, nullable/non-nullable)
- Half-baked null safety solutions where the runtime can still produce nulls even when the type system says otherwise
- Inconsistent tooling where the community is split across multiple formatters, build tools, and conventions
We need a new language - one with modern concepts and no ecosystem baggage. Dovetail is that language: garbage collected, fast to compile, with a clean type system, proper error handling, and consistent tooling from day one.
Design Philosophy and Principles
Section titled “Design Philosophy and Principles”Dovetail is built around several core principles:
Fast Compilation
Compilation should feel instant. Dovetail prioritizes fast feedback loops over maximum runtime optimization. The target competition is Python and Node.js: the goal is to pair their productive development experience with the performance opportunities of compiled WebAssembly.
Beautiful Code
Dovetail is designed to produce readable code that flows like English:
- String interpolation without prefixes:
"Hello, $name!" - Named arguments for clarity:
createUser(name = "John", age = 30) - Layout-sensitive syntax eliminates visual noise
- No cryptic abbreviations -
functionnotfn,ComparablenotOrd,EquatablenotEq - Keywords instead of operators where it improves readability (
and,or,not)
Strong Type System
The type system helps eliminate bugs:
- No null values - use
Option<T>instead - Discriminated unions (enums) for modeling data
- Traits for shared behavior
- Result types for error handling - no exceptions
Great Tooling
Dovetail includes excellent tools from day one:
- Integrated package manager and build tool
- Language Server Protocol (LSP) support
- Built-in formatter with
dovetail fmtand format-on-save in VS Code - Built-in skills for coding agents - Guidance for writing idiomatic Dovetail, applying best practices, and using specialized sub-agents for code review (planned for the public release)
- REPL for exploration (planned)
Target Platform (WasmGC)
Section titled “Target Platform (WasmGC)”Dovetail compiles to WebAssembly with Garbage Collection (WasmGC). This provides:
- Portability - Target hosts that support WasmGC and the WASI interfaces your program uses
- Performance - Designed for near-native execution through WebAssembly and Wasmtime.
- Safety - WebAssembly’s sandboxed execution model
- Interoperability - Use WASI for system access
Dovetail targets WebAssembly 3.0 and WASI Preview 3. dovetail run uses Wasmtime for local execution; you can also deploy the compiled component to other hosts that support the required WebAssembly features and WASI interfaces.
Dovetail uses traits for generic behavior and interfaces for contracts that can also be stored and passed as values. See Interfaces and Interface Types and Traits and Implementations.
Comparison with Other Languages
Section titled “Comparison with Other Languages”This is a high-level comparison of the design choices motivating Dovetail. Fast compilation is a design goal, not a benchmark result; ecosystem consistency is the direction we are building toward.
| Feature | Dovetail | TypeScript | Python | Java | Kotlin | Go | C# | Rust |
|---|---|---|---|---|---|---|---|---|
| No Nulls | Yes | No | No | No | Partial | No | Partial | Yes |
| No Exceptions | Yes | No | No | No | No | Yes | No | Yes |
| Consistent Async | Yes | No | No | No | Yes | No | Yes | Yes |
| Ad-hoc Polymorphism (Traits) | Yes | No | No | No | No | Partial | No | Yes |
| Sum Types | Yes | Yes | No | No | Yes | No | No | Yes |
| Layout-Sensitive | Yes | No | Yes | No | No | No | No | No |
| Garbage Collected | Yes | Yes | Yes | Yes | Yes | Yes | Yes | No |
| Fast Compilation | Yes | Yes | Yes | No | No | Yes | No | No |
| No Ecosystem Baggage | Yes | No | No | No | No | No | No | Yes |
1.2 Installation and Setup
Section titled “1.2 Installation and Setup”Installing prebuilt binaries
Section titled “Installing prebuilt binaries”No Rust toolchain is needed. The CLI includes the runtime used by dovetail run.
On macOS (Intel or Apple Silicon) and Linux (x86_64 or ARM64, glibc):
curl -fsSL https://dovetaillang.org/install.sh | shOn Windows x64, use PowerShell:
irm https://dovetaillang.org/install.ps1 | iexThe scripts install the website’s release and verify the executable’s SHA-256
checksum before replacing an existing installation. macOS and Linux require
curl and either sha256sum or shasum. Linux binaries use glibc and need a system
compatible with the Ubuntu 24.04 build environment; Alpine/musl is not supported.
The default directory is ~/.local/bin on macOS/Linux and
%LOCALAPPDATA%\Dovetail\bin on Windows. Add it to your PATH as printed by the
installer. The scripts do not edit your shell profile or Windows environment.
For a specific release or installation directory, download the script first:
curl -fsSL https://dovetaillang.org/install.sh -o install.shsh install.sh --version v0.1.4 --install-dir "$HOME/.local/bin"PowerShell scripts accept -Version v0.1.4 and -InstallDir PATH. Both scripts
are served by this website and download binaries from the matching
GitHub release.
Installing with Cargo
Section titled “Installing with Cargo”With a Rust toolchain installed, build the Dovetail CLI from crates.io with:
cargo install dovetail-lang --lockeddovetail-lang is the package name; the command you run is dovetail. Cargo builds
and installs the executable in its bin directory (usually ~/.cargo/bin/). Make
sure that directory is on your PATH. The CLI includes the runtime used by
dovetail run, so you don’t need to install Wasmtime separately.
cargo install dovetail-lang also works; --locked uses the dependency versions
recorded for the release.
Installing from Source
Section titled “Installing from Source”To try the current development version or work on the compiler, install from a repository checkout instead:
- Clone the repository:
git clone https://github.com/somdoron/dovetail.gitcd dovetail- Build the project:
cargo build --release- Install the Dovetail CLI:
cargo install --path dovetail --lockedThis installs the dovetail command to your Cargo bin directory (usually ~/.cargo/bin/).
Verifying the Installation
Section titled “Verifying the Installation”Verify Dovetail is installed correctly:
dovetail --versiondovetail --helpThe help output lists commands including init, projects, deps, fmt,
build, check, run, test, and lsp-server. Use dovetail <command> --help
for details about a particular command.
When working on the compiler itself, use cargo run -- <command> from its checkout
to test the current source. See Tool Commands for more details.
1.3 Editor Setup
Section titled “1.3 Editor Setup”VS Code Extension
Section titled “VS Code Extension”Dovetail provides a VS Code extension for the best development experience.
Installing the Extension
Section titled “Installing the Extension”Download dovetail-language-<version>.vsix from the matching
GitHub release. In VS Code, run
Extensions: Install from VSIX… from the Command Palette and select the file.
Install the compiler separately using the installation instructions above.
To build the extension from a repository checkout:
- Open VS Code
- Navigate to the
vscode-dovetaildirectory in the Dovetail repository - Run:
npm ci- Package the extension:
npm run package- Install the generated
.vsixfile in VS Code:- Open Command Palette (Cmd/Ctrl + Shift + P)
- Select “Extensions: Install from VSIX…”
- Choose the generated
.vsixfile
Extension Features
Section titled “Extension Features”The Dovetail VS Code extension provides:
- Syntax highlighting - Colorized Dovetail code
- LSP support - Real-time error diagnostics, autocomplete, go-to-definition
- Hover documentation - View type information on hover
- Find references - Find all usages of a symbol
- Workspace symbols - Quick navigation to types and functions
- Formatting - Format a document or format automatically on save
Configuration Options
Section titled “Configuration Options”The extension can be configured in VS Code settings:
| Setting | Default | Description |
|---|---|---|
dovetail.serverPath |
"dovetail" |
Path to the Dovetail executable |
dovetail.serverConnection |
"stdio" |
LSP transport (stdio or tcp) |
dovetail.serverPort |
9257 |
TCP port for LSP when dovetail.serverConnection is tcp |
dovetail.trace.server |
"off" |
Trace communication with LSP server |
To enable format-on-save:
{ "[dovetail]": { "editor.defaultFormatter": "dovetail-lang.dovetail-language", "editor.formatOnSave": true }}See Formatting for the formatter’s style and options.
1.4 Your First Dovetail Program
Section titled “1.4 Your First Dovetail Program”Creating a Project with dovetail init
Section titled “Creating a Project with dovetail init”Create a new Dovetail project using the init command:
mkdir my-projectcd my-projectdovetail init helloThis creates:
Dovetail.toml- The project manifest.gitignore- Excludes the local.dovetail/cachehello/src/main.dove- The main source file
For a library project, use dovetail init mylib and replace the generated main
with your library declarations. A library has no main entry point; init does
not have a separate --lib flag.
The Dovetail.toml Manifest File
Section titled “The Dovetail.toml Manifest File”The generated Dovetail.toml looks like this (the compiler version matches the CLI you installed):
compiler-version = "0.1.4"
[[project]]name = "hello"root_package = "hello"packages = ["."]Key fields:
compiler-version- The exact compiler version required by the workspace[[project]]- Project definition (can have multiple)name- Project nameroot_package- The root package name for this projectpackages- Package directories relative to the project’ssrc/directory
Project Directory Structure
Section titled “Project Directory Structure”After running dovetail init hello, your directory looks like:
my-project/├── .gitignore├── Dovetail.toml└── hello/ └── src/ └── main.doveConvention:
- Each project has its own directory matching the project name
- Source files go in
src/ - Test files go in
test/(for integration tests) - The directory structure under
src/determines package names
Writing “Hello, World!”
Section titled “Writing “Hello, World!””Open hello/src/main.dove and replace its contents with this complete example:
package hello
function greeting(name: String): String = "Hello, $name!"
function main(): Unit = debug(greeting("World"))
test "greets the supplied name" = assert greeting("Dovetail") == "Hello, Dovetail!"Let’s break this down:
package hello- Declares this file belongs to thehellopackagefunction greeting(...)- Builds a greeting using string interpolationfunction main(): Unit- The entry point for an application=followed by indented code - The function bodydebug(...)- Prints a value and a newline for a quick diagnostictest "greets the supplied name"- Checks the greeting with an assertion
This complete example is checked in CI. See Book validation
for what is checked; other snippets in the book may show only part of a program.
For application console output with typed I/O errors, see
Console.writeLine in the library guide.
Building and Running
Section titled “Building and Running”Run these commands from the directory containing Dovetail.toml.
Format your code:
dovetail fmtUse dovetail fmt --check to check formatting without changing files.
Build the project:
dovetail buildThis compiles your code and produces build/hello.wasm.
Build and run:
dovetail runOutput:
Hello, World!Type check without building:
dovetail checkThis verifies your code is correct without generating a WebAssembly file - useful for quick feedback during development.
Run the test:
dovetail testThe test checks that greeting("Dovetail") returns "Hello, Dovetail!". You’ll learn
more about testing in Part 15.
Summary
Section titled “Summary”You now have Dovetail installed and know how to:
- Create a new project with
dovetail init - Understand the project structure and
Dovetail.toml - Write and run a simple program
- Use the VS Code extension for a better development experience
In the next part, we’ll explore the Dovetail CLI commands in more detail.
