Values In Bracket Expression
Configuration that actually makes sense. No YAML indentation nightmares. No JSON comma catastrophes. Just clean, readable config.
# Your config file π
app {
name "My Awesome App"
version 2.1.0
debug false
database {
host db.example.com
port 5432
ssl true
}
servers [web1 web2 api]
}
Simple syntax rules that make sense
key value
config { key value }
items [one two three]
# Full line comment port 8080 # Inline
count 42 price 19.99 enabled true name "text"
app { db { host localhost } }
Everything in VIBE uses these simple building blocks
That's it. No colons, no equals, no commas, no
semicolons.
Simple syntax = Fast parsing = Happy
developers
Configuration that finally feels right
Just 5 token types. No commas, semicolons, or complex punctuation. Natural whitespace separation keeps it clean.
Automatic type inference. Numbers look like numbers, booleans are obvious. No explicit declarations needed.
Full-line or inline # comments. Document your config without special syntax or breaking structure.
Single-pass, O(n) parsing over an explicit stack β no recursion, no backtracking. Deeply nested input can't overflow the C stack, and memory stays bounded.
Structure is instantly obvious. Braces create clear boundaries. Indentation is visual-only, not syntactic.
Full UTF-8 support in strings and comments. ASCII identifiers ensure maximum speed and compatibility.
One header, zero dependencies. make builds
libvibe.a and a versioned
libvibe.so; make install ships a
vibe.pc so pkg-config just works.
Enforced resource limits and a closed set of stable error
codes. Untrusted input fails closed with a category like
nested-container β never silent truncation.
vibe_emit() serialises a value tree back to
canonical VIBE, and the vibe fmt formatter is
idempotent β parse, edit, and write back with confidence.
Install libvibe, link it with pkg-config, or vendor two files
# build the static + shared library and the `vibe` CLI
git clone https://github.com/1ay1/vibe.git && cd vibe
make
sudo make install # libvibe.a/.so, vibe.h, vibe.pc, vibe
# then, in your own project:
cc app.c $(pkg-config --cflags --libs vibe) -o app
vibe check config.vibe # validate; structured error on failure
vibe fmt config.vibe # canonical reformat (-w rewrites in place)
vibe get config.vibe server.port # read a scalar by dotted path
#include <vibe.h>
VibeError err;
VibeValue *cfg = vibe_parse(src, len, &err);
if (!cfg) { /* err.code: unclosed-object, nested-container, ... */ }
const char *host = vibe_get_string(cfg, "server.host");
int64_t port = vibe_get_int(cfg, "server.port");
char *text = vibe_emit(cfg); // canonical VIBE; round-trips
vibe_free(text);
vibe_value_free(cfg);
Prefer to vendor? Drop vibe.c and vibe.h
into your tree β the whole parser is two files and the C standard
library. Full API in
API.md.
Visual guide to VIBE syntax structure
A simple key-value pair. The identifier (key) is followed by a value, separated by whitespace. No colons, equals signs, or other separators needed.
Objects group related configuration. They start with an identifier, followed by an opening brace {, contain statements (assignments, nested objects, or arrays), and end with a closing brace }.
Arrays hold multiple values of the same or different types. Values are separated by whitespace (no commas!). Arrays can be inline or multi-line.
VIBE supports five value types with automatic inference: strings (quoted or unquoted), numbers (integers and floats), booleans (true/false), nested objects, and arrays.
Comments start with # and continue to the end of the line. They can appear on their own line or after any value. Comments are not preserved in the parsed output.
A VIBE file consists of zero or more statements. Each statement can be an assignment, an object definition, an array definition, or a comment. Statements are separated by newlines.
Join developers who choose clarity over complexity