Install
One binary: compiler, tests, formatter, WebAssembly, language server, debugger and MCP. Nothing else to install.
Download Deed 0.2.13
Pick the machine this browser is on. Each button downloads the released archive directly from GitHub.
These archives are unsigned. For automatic checksum verification
and a deed command on your PATH, use the
installer below. Intel Macs and Linux ARM machines can
build with Rust.
Install and verify automatically
On Linux, or on an Apple-silicon Mac:
$ curl -fsSL https://raw.githubusercontent.com/deed-lang/deed/main/install.sh | sh
On Windows:
> irm https://raw.githubusercontent.com/deed-lang/deed/main/install.ps1 | iex
Either one works out which release asset fits the machine, downloads
it along with the checksum list the release published, refuses it if
the hash does not match, and leaves one file in your own profile:
~/.local/bin, or
%LOCALAPPDATA%\Programs\deed. It never asks for a
password, because it never writes anywhere that would need one, and
there is nothing to uninstall but the file.
What the hash buys is worth stating exactly, since a
sha256 in an install script tends to read like it proves
more than it does. The checksums come from the same release as the
binary, so this catches a truncated or corrupted download and does
not catch a compromised release.
Piping a script into a shell is a thing worth being uneasy about.
Both scripts are short and are in the repository beside the compiler
— install.sh
and
install.ps1
— and the rest of this page is the same work done by hand.
Unpack it and ask it what it is
Pick the one for your machine and run it as written. The last line is what you should see.
Linux
$ tar xzf deed-v0.2.13-x86_64-unknown-linux-gnu.tar.gz
$ ./deed-v0.2.13-x86_64-unknown-linux-gnu/deed --version
deed 0.2.13
macOS
$ tar xzf deed-v0.2.13-aarch64-apple-darwin.tar.gz
$ xattr -d com.apple.quarantine deed-v0.2.13-aarch64-apple-darwin/deed
$ ./deed-v0.2.13-aarch64-apple-darwin/deed --version
deed 0.2.13
The middle line is not optional and it is explained below.
Windows
> Expand-Archive deed-v0.2.13-x86_64-pc-windows-msvc.zip .
> .\deed-v0.2.13-x86_64-pc-windows-msvc\deed.exe --version
deed 0.2.13
What your operating system will say about it
These binaries are not code-signed. Signing needs a certificate tied to an identity, and there is not one yet, so both macOS and Windows will treat the download as something they have never seen.
macOS marks anything a browser downloaded with a
quarantine attribute, and refuses to run an unsigned, unnotarised
binary that carries it. Depending on the version you get
“cannot be opened because the developer cannot be
verified” or the process is killed with no explanation at
all. Removing the attribute is the xattr line above, and
it is worth understanding rather than pasting: it says you accept
this file from where you got it.
Windows shows “Windows protected your PC” if you double-click the executable in Explorer. More info, then Run anyway. Starting it from a terminal, as above, is the shorter path.
Linux says nothing. The archive carries the execute
bit; if you rebuilt it or copied it in a way that dropped the mode,
chmod +x deed.
Where to put it
Anywhere. It reads nothing next to itself and writes nothing beside
itself. The one-line install has already put it somewhere your shell
looks; if you unpacked it by hand and want to type
deed instead of a path, move it onto yours:
$ sudo mv deed-v0.2.13-x86_64-unknown-linux-gnu/deed /usr/local/bin/deed
On Windows, put the folder on Path through Settings, or
keep using the full path. Nothing on this page needs it on
Path.
A first program
deed new writes one, rather than leaving you to work the
module header and the file layout out of a repository:
$ deed new greeter
greeter/greeter.deed
greeter/main.deed
next: cd greeter && deed test .
$ cd greeter
$ deed test .
./greeter.deed
ok a greeting carries the name it was given
ok there is no greeting for nobody
ok property greeting (100 cases)
3 passed, 0 failed
$ deed run main.deed
hello, world
Three tests out of two files, and only two of them are written down.
The third is generated from the contract on greeting,
which is the point: a signature is checked rather than read.
By hand instead, the whole of a program is this much:
module hello
fn main(sys: System) -> Int
uses
Io.write,
{
Io.write(sys.console, "hello, world\n")
0
}
Then:
$ deed check hello.deed
$ deed run hello.deed
hello, world
check printing nothing is the answer. It found no
problem, so it has nothing to say, and it exits 0. Anything it does
print is a diagnostic, and it will point at the byte it means.
The playground runs the same compiler in a browser tab, so you can try things there without any of this.
What else is in it
The same file with a different first word each time. None of them
needs anything else on the machine, and
deed --help is the longer version of this table.
| Command | What it is |
|---|---|
deed new |
A project: a library module with a contract and its tests, and a program that imports it. No manifest, because a new project has no code outside its own tree. |
deed check |
The compiler. Silence is the answer. |
deed test |
The test blocks, and the properties a contract generates. It refuses to run anything that does not check. |
deed run |
Calls main, handing it the one
System capability there is.
|
deed build |
Compiles to WebAssembly. With --component, writes
the .wit world the effect rows add up to, which is
the one clause page.
|
deed doc |
A module's API reference, as Markdown. No visibility modifiers here, so there is nothing to decide about what belongs on it. |
deed fmt |
One canonical form, and no options for the output. |
deed fix |
Applies the repairs that are certain and leaves the guesses alone. |
deed explain |
The page for one diagnostic code. Every code has one. |
deed lsp |
A language server, for an editor to start rather than you. |
deed debug |
A debug adapter: breakpoints, stepping, and the stack and bindings of every active call. |
deed mcp |
A Model Context Protocol server, so an agent can ask the compiler the questions an editor asks. |
The last one is worth a second sentence, because the argument this
language is built on is that most code is no longer typed out by a
person. deed mcp holds no capability: a program arrives
as text and the answer leaves as text, and nothing it runs can reach
a file. What it hands back is not only the diagnostics but which tier
each obligation landed in, so the thing writing the code can see the
difference between a contract that was proved and one that was left
to a runtime check.
With Rust instead
Needs Rust 1.88 or newer, and nothing else:
$ cargo install deed-lang
deed on crates.io belongs to somebody else, so the
package is deed-lang. The binary it installs is
deed, and it is the same one file this page has been
talking about.
From a clone, if you want the tree it was built from:
$ git clone https://github.com/deed-lang/deed
$ cd deed
$ cargo install --path crates/deed-cli
The workspace has no external dependencies, so either way this compiles the compiler and nothing from anywhere else.
When it does not work
cannot execute binary file: Exec format error-
The file is for a different machine than the one running it. Check
the table above against
uname -m. deed: command not found-
It is not on your
PATH. Run it by path, with the./, or move it as above. --versionprints something other than 0.2.13-
You are running a different
deedthan the one you unpacked.which deedsays which. - It prints a diagnostic you do not understand
-
deed explain DEED5001, with the code it printed. Every code has a page. - Anything else
- Open an issue with the command you ran and everything it printed. A confusing message is a bug in the message.