Introduction

cx is a general-purpose programming language for writing fast software productively. It compiles to efficient native code, gives you full low-level control when you need it, and offers high-level conveniences the rest of the time, all without a garbage collector or hidden runtime.

The language is simple and unopinionated, supporting imperative, generic, data-oriented, functional, and object-oriented programming. Its syntax belongs to the C family, so if you have used a language with curly braces and int x = 1; declarations, cx code should look familiar from the start.

struct Image {
    int width;
    int height;
}

Result<Image, string> makeImage(int width, int height) {
    if width <= 0 || height <= 0 {
        return Err("dimensions must be positive");
    }
    return Ok(Image(width = width, height = height));
}

void main() {
    for size in [640, -1, 1920] {
        switch makeImage(size, size) {
            case Ok img: println(img.width, "x", img.height);
            case Err e: println("rejected: ", e);
        }
    }

    var evenSquares = List([1, 2, 3, 4, 5, 6]).filter(n => n % 2 == 0).map(n => n * n);
    println(evenSquares);
}

This small program already shows several things cx is built around: plain structs, errors returned as values and handled with switch, named arguments, type inference with var, and lazy iterator chains with lambdas. Code examples on the website can be edited and run directly in the browser, or you can install the compiler as described in Getting started.

Who cx is for

cx is a general-purpose language designed especially for areas where you want both low-level control and high-level expressiveness in one language: gamedev, graphics, system software, simulations, tools, and other performance-sensitive applications where debug performance and quick prototyping matter.

It aims to combine the control and performance of C, C++, Zig, or Odin with the expressiveness of a higher-level language: compile-time null safety, method call syntax, closures, generics with interface bounds, operator overloading, tagged unions, and a capable standard library, while keeping the language small and approachable. Design principles explains the goals behind this and what cx deliberately does not try to be, and Comparison with related languages covers how it differs from each of those languages.

Project status

cx is approaching its 0.1 release. The language is already usable and being used for writing real software, but some planned features are not implemented yet, some existing features may still change, and there are still some bugs. It is a good fit for projects that don't require a 100% stable foundation, or backwards compatibility, or a mature ecosystem. If you use it, questions are warmly welcome and feedback is greatly appreciated on GitHub and the Discord server.

Frequently asked questions

Do I need to import the standard library or other files in my project?

No. The standard library is visible to all code automatically, and all .cx files in your project (except build.cx and vendored libraries under vendor/) compile as one module, so neither needs import. Only external code needs importing: dependencies, vendored libraries, and other directories outside your project. See Modules and imports.

Is cx memory-safe?

References, slices, strings, and iterators are checked at compile time, but raw pointers are unchecked and there are no Rust-style lifetime annotations or guarantees. See Safety by default and cx vs Rust.

How do I build a project and add dependencies?

Run cx run in the project directory; it works with no configuration. Dependencies can either be Git repositories declared in build.cx, or vendored code alongside your code. You import both by package name. Run tests with cx test. See Build system.

How do I use existing C or C++ code?

Import C/C++ headers directly (import "MyHeader.h") and call their functions like ordinary cx functions; individual C functions can also be declared with extern. C++ interop with extern "C++" only supports basic C-like language constructs for now; a more full-featured C++ interop is a longer-term goal. See Using C libraries.

Which build mode should I use?

The default debug mode compiles fast with safety checks enabled. Use --release for fully optimized builds with checks disabled (overflow wraps), or --release-safe for optimized builds that keep the checks. See Build modes.

There is no preprocessor or macros - how do I conditionally compile code?

Use #if with -D defines. Predefined platform-conditions use #if Windows for example, both in source files and in build.cx. See Conditional compilation.

Not to be confused with

cx shares its name with several unrelated languages:

Where to go next