Skip to content
Crystal CodeDocs
ENEnglish

Build from source

Crystal Code is built from two repositories placed side by side. The engine, tools, providers, and plugins reference the Crystal library by relative path, so the checkout next to this repository must be named Crystal.

  • The .NET 10 or .NET 11 SDK. global.json asks for 10.0.0 with rollForward: latestMajor and allows prerelease SDKs.
  • Git.
  • bash on the PATH. On Windows, Git Bash provides it.
  • A TTY for the interactive UI. Building and testing do not need one.
  • An API key only to run a session, not to build.

Pick a parent directory and clone both repositories into it:

Terminal window
mkdir -p ~/src
cd ~/src
git clone https://github.com/YELANDAOKONG/CrystalCode.git
git clone https://github.com/YELANDAOKONG/Crystal.git

The result must look like this:

~/src/
├── Crystal/
└── CrystalCode/

The relative references are literal paths such as ../../Crystal/Crystal/Crystal.csproj and ../../Crystal/Crystal.Tools/Crystal.Tools.csproj. They are used by CrystalCode.Engine, CrystalCode.Tools, CrystalCode.Providers, and CrystalCode.Plugins. Renaming the CrystalCode folder is safe. Renaming the Crystal folder breaks restore.

Confirm the layout and the SDK before building:

Terminal window
cd ~/src/CrystalCode
ls ../Crystal/Crystal/Crystal.csproj
dotnet --version

dotnet --version must start with 10. or 11.. The install script checks that major version and stops otherwise.

From the CrystalCode repository root:

Terminal window
dotnet build CrystalCode.sln
dotnet test CrystalCode.sln

CrystalCode.sln contains the executable project CrystalCode, the CrystalCode.Engine class library, and the display, tools, providers, and plugins projects with their test projects. The Crystal projects are built through the project references, not listed in this solution.

Terminal window
export DEEPSEEK_API_KEY="..."
dotnet run --project CrystalCode -- --provider deepseek --model deepseek-flash

To open another directory as the workspace, pass --workspace among the application arguments, after the final --:

Terminal window
dotnet run --project CrystalCode -- --workspace ~/projects/app \
--provider deepseek --model deepseek-flash

An interactive run needs a TTY. crystal run is the non-interactive form described in Headless runs.

Install this checkout for local development

Section titled “Install this checkout for local development”

From the repository root on Linux or macOS:

Terminal window
sh scripts/install-local.sh

On Windows:

Terminal window
powershell -ExecutionPolicy Bypass -File scripts/install-local.ps1

The script resolves the repository from its own path, so it can be run from any working directory. It prints each check before it continues.

Check Requirement
Repository CrystalCode.sln and CrystalCode/CrystalCode.csproj exist
Commands dotnet, grep, cp, mv, find, chmod, mkdir, rm, touch, uname, and tail are on the PATH (Unix)
.NET SDK The selected SDK major version is 10 or 11
Crystal sibling ../Crystal contains Crystal/Crystal.csproj, Crystal.Tools/Crystal.Tools.csproj, Crystal.Agents/Crystal.Agents.csproj, and Crystal.Harness/Crystal.Harness.csproj
Platform The OS and architecture map to a supported runtime identifier
Install destination ~/.crystal/binaries/code is writable, is not a symbolic link, and is not a regular file
Running process No process named CrystalCode is running
Publish output build/CrystalCode exists, is executable, has no CrystalCode.dll beside it, and is at least 10,000,000 bytes
Staged copy The staged and installed binaries match the published size
Platform Runtime identifier
Linux x64 linux-x64
Linux ARM64 linux-arm64
macOS Apple silicon osx-arm64
macOS x64 under Rosetta osx-arm64
macOS x64 without Rosetta Rejected: macOS x64 is not supported.
Windows x64 win-x64

The script publishes Release into build/ with the same arguments as the release workflow:

dotnet publish CrystalCode/CrystalCode.csproj
--configuration Release
--runtime <rid>
--self-contained true
-p:PublishSingleFile=true
--output build

The workflow writes ./publish for the GitHub asset. This script writes build/, which is gitignored. The publish includes the runtime, so the resulting single file is large. The script rejects a binary smaller than 10 MB because that indicates the runtime was not bundled.

The output is copied to a staging directory, code.new, next to the install directory. The current code directory is renamed to code.previous, the staged directory is moved into place, then the backup is removed. A failure or interrupt before the move restores code.previous. Symbolic links are refused.

Only the binaries under ~/.crystal/binaries/code/ are replaced. Configuration, credentials, prompts, sessions, plugins, and tools stay in place.

On Linux and macOS, the script writes a block to the profile for the current shell:

  • zsh: ~/.zshrc
  • bash: ~/.bashrc
  • any other shell: no profile is changed

The block is marked # Crystal Code CLI (Installer) and adds:

Terminal window
export PATH="$HOME/.crystal/binaries/code:$PATH"
alias crystal=CrystalCode

The block is written once. Re-running the script updates a partial or legacy block instead of appending a duplicate. Open a new terminal or source the profile, then run crystal.

On Windows, the install directory is added to the user-level PATH. The command stays CrystalCode.

For a shell with no profile block, start the installed binary directly:

Terminal window
~/.crystal/binaries/code/CrystalCode

To publish without installing, run the command above yourself, choosing the runtime identifier for this machine. The executable project is CrystalCode, the Spectre application name is crystal, and the session engine lives in the CrystalCode.Engine class library.

Message Cause and fix
Missing sibling Crystal checkout: ... Clone https://github.com/YELANDAOKONG/Crystal.git into the directory next to the CrystalCode repository and name it Crystal.
Missing Crystal project: ... The sibling checkout is incomplete or from an older revision. Update it with git pull.
Crystal Code requires the .NET 10 or .NET 11 SDK. Install a supported SDK. Check dotnet --version; global.json rolls forward to the latest major SDK.
Crystal Code is running. Exit it, then run this script again. Close every running CrystalCode process.
macOS x64 is not supported. Native Intel macOS is not a release target. On Apple silicon under Rosetta the script uses osx-arm64.
Published binary is ... bytes. The publish was not self-contained or did not finish. Run the publish command again.