Library / SDK
GNOME/vala avatar
GNOME/vala

Vala: C#-shaped syntax over the GObject ABI, with a compiler that compiles itself

Read-only mirror of https://gitlab.gnome.org/GNOME/vala

888 stars85 forksValaLGPL-2.1

At a glance

What is it?
Vala is a programming language that brings modern language features to GNOME developers without imposing runtime requirements and without using a different ABI from C code, and its compiler valac translates Vala into C. It suits GNOME contributors and anyone who wants high-level code in a stack that is still C underneath, and building it is a bootstrap exercise because the compiler is self-hosting.
Who is it for?
Vala fits a GNOME developer who wants properties, signals, interfaces and generics over the GObject type system without introducing a runtime into a C stack, and it fits a project that already depends on GLib or GTK+ because binding a C library is a matter of supplying an API file rather than writing a binding generator.
Can I use it commercially?
Yes, with conditions. LGPL-2.1 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
Is it still maintained?
Yes. The repository last received commits 52 days ago.
What is it written in?
Mainly Vala, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A language with no runtime of its own

Vala is described as a programming language that aims to bring modern programming language features to GNOME developers without imposing any additional runtime requirements and without using a different ABI compared to applications and libraries written in C.

Both halves of that sentence matter. There is no Vala runtime that your C application has to link against or ship, and the compiled output is ordinary C that talks to the same GObject machinery everything else in GNOME already uses. The practical consequence is that a Vala program and a C program are not two different things on the wire or in memory; they are the same thing written in two syntaxes.

The syntax is similar to C#, modified to better fit the GObject type system. The list of supported modern features is the feature list of a language designed for desktop work: interfaces, properties, signals, foreach, lambda expressions, type inference for local variables, generics, non-null types, assisted memory management and exception handling.

Two of those deserve a note for anyone coming from C. Properties are the central idea, since they map onto GObject's get and set accessors, and signals map onto GObject signals, so the familiar C API becomes a much nicer surface in Vala. Assisted memory management means the compiler inserts the reference counting calls for you, which is the single largest source of manual bookkeeping in GObject C code.

The audience is therefore GNOME developers specifically, not application developers in general. The primary language of the repository is Vala, the licence is LGPL-2.1, and the default branch is main.

One housekeeping note first, because it affects how you treat the repository itself. The description says this is a read-only mirror of the GNOME Vala repository on GitLab, and the homepage is gitlab.gnome.org/GNOME/vala. The last push was on 2026-09-01, so the mirror is current, but commits and issues belong upstream.

valac emits C and headers, and the GObject type system does the rest

The compiler is the mechanism, and it is unusual in a specific way.

valac, the Vala compiler, is a self-hosting compiler that translates Vala source code into C source and header files. It uses the GObject type system to create classes and interfaces declared in the Vala source code.

That last sentence is the part with the widest consequences. A Vala class is not a new kind of object that a Vala-specific runtime knows about. A Vala class is a GObject class, and the generated C is the C you would have written by hand to express the same thing, with the boilerplate filled in. A Vala interface is a GObject interface.

The interoperability story is described explicitly in the README, and it is the reason the language has survived in a C world. Using classes and methods written in Vala from an application written in C is not difficult: the Vala library only has to install the generated header files, and C applications may then access the GObject-based API of the Vala library as usual.

The reverse direction is also anticipated, and it is the cleverest claim in the README. It should be easily possible to write a bindings generator for access to Vala libraries from applications written in, for example, C#, because the Vala parser is written as a library, so that all compile-time information is available when generating a binding. That is a specific architectural commitment rather than a hope: the parser is a library so that other tools can consume it, which is what makes a C# binding for a Vala library a mechanical job rather than a research project.

The alternative approach, and the one every other language takes, is to write runtime bindings for the C library. The README states the difference plainly: Vala is designed to allow access to existing C libraries, especially GObject-based ones, without the need for runtime bindings. All that is needed to use a library with Vala is an API file containing the class and method declarations in Vala syntax.

That is the whole bargain. You do not bind a C library at runtime, you describe it once in a .vapi file, and Vala calls into it as if it were compiled in.

API files instead of runtime bindings, and the vapi/ directory

The API file mechanism is what makes the library story concrete, and the repository layout shows how large the catalogue has become.

The vapi/ directory at the root of the tree holds the API files, and the presence of a vapigen/ directory alongside it shows that some of them are generated rather than hand-written. The vapigen tool reads introspection data, which is where gobject-introspection in the build requirements comes from, and emits a Vala API description from it. For a library that already ships GObject introspection data, that is the difference between a day of hand-writing declarations and a generated file.

Vala currently comes with bindings for GLib and GTK+, which is the starting point for anyone using the language, since those are the two libraries nearly every GNOME application needs. The build requirement of gobject-introspection is consistent with that: the tool reads .gir and .typelib data to produce the API files.

The interop story in the other direction, writing an application in C that uses a Vala library, is simpler still. The Vala library installs its generated header files, and the C application includes them and uses the GObject API as usual. There is no wrapper object to cross, because there is no wrapper.

The consequence for a reviewer or a user is that Vala is a language for a specific ecosystem rather than a general one. A project with no GLib dependency gets much less from it, because the entire convenience of the language comes from the GObject type system being present, and the value of the .vapi approach is greatest for libraries that already have introspection data.

So the practical test for any candidate library is quick: does a .vapi file exist for it, and if not, can vapigen produce one? If yes, Vala is a cheap way in. If the library is a plain C library with no introspection data and no .vapi file, you are writing the API description by hand, and the argument for Vala over C is much weaker.

Bootstrapping the compiler, which is the real installation

Building Vala is the one genuinely awkward part of using it, and the README is refreshingly direct about why.

Vala is self-hosting so it needs another Vala compiler to compile itself. The executable is valac, and it can be installed from an existing package, built from a source tarball, or built from the Vala bootstrap module. If you already have a valac on the machine, step two is done and you move to step three.

The build dependencies for step one are a C compiler such as GCC, a C library such as glibc, glib at version 2.56 or newer, gobject-introspection, flex, bison, Graphviz libgvc at 2.16 or newer to build valadoc, make, autoconf, autoconf-archive and libtool. Documentation generation adds help2man for the man pages, sphinx with python-furo, and latexmk with texlive for PDF output.

The bootstrap from a release tarball, using 0.48.25 as the example, is five commands:

sh
curl --silent --show-error --location https://download.gnome.org/sources/vala/0.48/vala-0.48.25.tar.xz --output vala-bootstrap.tar.xz
tar --extract --file vala-bootstrap.tar.xz
cd vala-bootstrap
./configure --prefix=/opt/vala-bootstrap
make && sudo make install

The configure script checks whether valac can be found in PATH, and if it cannot, the compiler is bootstrapped from the C source files in the tarball. The README also points out that you do not have to install the bootstrapped compiler, because it is available in vala-bootstrap/compiler/valac, which is a libtool wrapper script that makes the libraries in the build directory work together.

The alternative bootstrap route uses the archive module, and the touch of the stamp files is what tells the build that no previous compiler is available:

sh
git clone https://gitlab.gnome.org/Archive/vala-bootstrap
cd vala-bootstrap
touch */*.stamp
VALAC=/no-valac ./configure --prefix=/opt/vala-bootstrap
make && sudo make install

Setting VALAC=/no-valac is the explicit way of saying there is no existing compiler, which makes the build take the bootstrap path rather than finding one by accident.

Step three then compiles the newest Vala from the repository using the compiler you now have, either straight from a clone with ./autogen.sh, or with VALAC pointed at the bootstrapped build.

The source tree, and the two C projects inside it

The top level of the repository shows a compiler that is a substantial piece of software in its own right, and it is worth mapping because the directory names are the documentation.

The compiler/ directory holds valac itself. The vapi/ directory holds the API files for the C libraries Vala can call, and vapigen/ holds the generator that produces many of them from introspection data. libvaladoc/ is the documentation generator, which is why Graphviz appears in the build requirements, since valadoc renders the class and inheritance diagrams. codegen/ and ccode/ are the code generation backends, which generate the C output. gobject-introspection/ holds the introspection tooling.

The build system is the autotools one, with configure.ac, Makefile.am, Makefile.common, build-aux/ and an autogen.sh script, plus vala.m4 for the autoconf macros and libvala.pc.in for the pkg-config file that lets other projects link against a Vala-built library.

The documentation side is thorough for a compiler project. There is a doc/ directory, and the tree carries a NEWS file, a COPYING file, AUTHORS and THANKS. The changelog history goes back a long way, with ChangeLog.pre-0-4 and ChangeLog.pre-0-5-7 as separate files.

There is also a vala.doap file, a standard GNOME project description file, and a.gitlab-ci.yml, which confirms that the GitLab repository is where the work happens and the GitHub copy is a mirror.

The tests/ directory is present at the root, alongside a.dir-locals.el, which is an interesting detail: an Emacs file descriptor locals file in the tree of a language compiler suggests that at least some of the contributors work on the code in Emacs with a project-specific configuration.

What it costs, what it does not do, and the LGPL terms

Two things are worth being blunt about.

The first is that Vala is not a general-purpose modern language. It is bound to GObject, to GLib and to the C ABI. The elegance of the properties and signals model comes directly from GObject having that model, and a project outside the GNOME ecosystem gets much less of the benefit for the same syntax. The README is honest about this by leading with GNOME developers rather than with programmers in general, and any evaluation should treat that framing as the scope rather than as a preference.

The second is the toolchain. Even a small Vala program needs a C compiler, glib, and a Vala compiler in the loop, and a self-hosting compiler means the build has a bootstrap step that most other language installs do not. That is fine for a GNOME distribution packager and heavy going for a team that just wants a nicer way to write a desktop utility. The install cost is real, and the README's own three-step structure measures it accurately.

The alternative approach is C with the GObject boilerplate written by hand or by a code generator, and the difference in approach is precise. In C, a property is a getter and a setter method pair that you write and register, a signal is a function pointer you emit and connect, and memory management is refcounting you do by hand. In Vala, the same concepts are language constructs, and the compiler generates the C that registers them. The generated C is the same C you would have written, which is why the ABI compatibility claim holds.

A related alternative is writing a C# binding for the same libraries, using the introspection data and a binding generator. The README anticipates exactly this and explains the difference: a Vala library can be consumed from C# because the Vala parser is written as a library and exposes the compile-time information a binding generator needs. So the choice is not between Vala and C#, it is between generating bindings for a C library and compiling to C in the first place.

On the licence, the project is LGPL-2.1, with the COPYING file at the root of the tree. This review does not interpret licence terms, and the practical point is that the licence of the language and its compiler is a separate question from the licence of the libraries you call through it.

Finally, a practical note on the mirror. The last push was on 2026-09-01 and the repository is not archived, but since this is a read-only mirror, your patches belong in the GitLab repository, and the wiki and issue discussions live there too.

Editorial conclusion

Vala fits a GNOME developer who wants properties, signals, interfaces and generics over the GObject type system without introducing a runtime into a C stack, and it fits a project that already depends on GLib or GTK+ because binding a C library is a matter of supplying an API file rather than writing a binding generator. It is the wrong choice if you want a standalone language with its own runtime, since the whole point is the absence of one, and it is the wrong choice for a team that has no C toolchain at all, because the build needs a C compiler, glib, flex, bison and autoconf before Vala itself is involved. Before you adopt it, read the vapi/ directory to see whether a usable API file already exists for the library you want to call, and remember that this GitHub repository is a read-only mirror, so changes and issues belong on gitlab.gnome.org.

Frequently asked questions

What is Vala and who is it for?

Vala is a programming language that aims to bring modern programming language features to GNOME developers without imposing any additional runtime requirements and without using a different ABI compared to applications and libraries written in C. Its syntax is similar to C#, modified to better fit the GObject type system.

How does Vala access existing C libraries?

All that is needed to use a library with Vala is an API file containing the class and method declarations in Vala syntax, so no runtime bindings are required. Vala currently comes with bindings for GLib and GTK+, and the repository has a vapi/ directory for the API files and a vapigen/ directory for the generator that produces them.

How do I build the Vala compiler from source?

Vala is self-hosting, so it needs another Vala compiler to compile itself. You install a C compiler, glib 2.56 or newer, gobject-introspection, flex, bison, Graphviz and the autotools, then bootstrap with a source tarball or the vala-bootstrap module, and finally build the repository with `./autogen.sh` and `make && sudo make install`.

Can a C application use a library written in Vala?

Yes. The Vala library only has to install the generated header files, and C applications may then access the GObject-based API of the Vala library as usual. The README also notes it should be possible to generate bindings for Vala libraries from other languages such as C#, since the Vala parser is written as a library.

Where do changes to Vala go, and what licence applies?

This GitHub repository is a read-only mirror of https://gitlab.gnome.org/GNOME/vala, which is where the work and the discussions belong, and the last push was on 2026-09-01. The project is released under the LGPL-2.1, with the COPYING file at the root of the tree.

Official sources

  1. GNOME/vala on GitHub
  2. Issues
  3. License: LGPL-2.1
  4. Project website
  5. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/gnome-vala.svg)](https://hysenlabs.com/projects/gnome-vala)

Was this useful?