✨ Pass the vibe check

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]
    }
5
Data Types
0
Reserved Words
1
Pass Parsing
100%
Human Readable

How VIBE Works

Simple syntax rules that make sense

Assignment
key value
Simple key-value pairs separated by whitespace
No colons, equals signs, or commas needed
Objects
config {
  key value
}
Nested structures using curly braces
Visual hierarchy is immediately clear
Arrays
items [one two three]
Space-separated values in square brackets
No commas, no dashes, just clean lists
Comments
# Full line comment
port 8080 # Inline
Hash symbol starts comments anywhere
Document freely without breaking syntax
Types
count 42
price 19.99
enabled true
name "text"
Smart automatic type inference
Numbers, booleans, strings just work
Nesting
app {
  db {
    host localhost
  }
}
Unlimited nesting depth for complex configs
Indentation is visual, not syntactic

Just 5 Token Types

Everything in VIBE uses these simple building blocks

IDENTIFIER
STRING
{ }
[ ]
# comment

That's it. No colons, no equals, no commas, no semicolons.
Simple syntax = Fast parsing = Happy developers

Why VIBE?

Configuration that finally feels right

Minimal Syntax

Just 5 token types. No commas, semicolons, or complex punctuation. Natural whitespace separation keeps it clean.

Smart Types

Automatic type inference. Numbers look like numbers, booleans are obvious. No explicit declarations needed.

Comments Anywhere

Full-line or inline # comments. Document your config without special syntax or breaking structure.

Lightning Fast

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.

Visual Clarity

Structure is instantly obvious. Braces create clear boundaries. Indentation is visual-only, not syntactic.

Unicode Ready

Full UTF-8 support in strings and comments. ASCII identifiers ensure maximum speed and compatibility.

Real C Library

One header, zero dependencies. make builds libvibe.a and a versioned libvibe.so; make install ships a vibe.pc so pkg-config just works.

Safe by Default

Enforced resource limits and a closed set of stable error codes. Untrusted input fails closed with a category like nested-container β€” never silent truncation.

Round-trips

vibe_emit() serialises a value tree back to canonical VIBE, and the vibe fmt formatter is idempotent β€” parse, edit, and write back with confidence.

A real library, not just a parser

Install libvibe, link it with pkg-config, or vendor two files

install
# 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
the vibe CLI
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
app.c
#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.

VIBE Grammar Railroad Diagrams

Visual guide to VIBE syntax structure

1

Assignment

identifier
β†’
value

A simple key-value pair. The identifier (key) is followed by a value, separated by whitespace. No colons, equals signs, or other separators needed.

Example:
host localhost
port 8080
enabled true
2

Object

identifier
β†’
{
β†’
statements
β†’
}

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 }.

Example:
database {
host localhost
port 5432
}
3

Array

identifier
β†’
[
β†’
value
β†’
value...
β†’
]

Arrays hold multiple values of the same or different types. Values are separated by whitespace (no commas!). Arrays can be inline or multi-line.

Example:
ports [80 443 8080]
hosts [
web1.example.com
web2.example.com
]
4

Value Types

string
unquoted or "quoted"
number
42 or 3.14
boolean
true or false
object
{ ... }
array
[ ... ]

VIBE supports five value types with automatic inference: strings (quoted or unquoted), numbers (integers and floats), booleans (true/false), nested objects, and arrays.

Example:
name "John Doe" # quoted string
url example.com # unquoted string
count 42 # integer
price 19.99 # float
active true # boolean
5

Comments

#
β†’
any text until end of line

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.

Example:
# This is a full-line comment
port 8080 # This is an inline comment
# Comments can contain Γ©mojis πŸš€ and Unicode!
6

Complete VIBE File

comment
β†’
statement
β†’
statement...

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.

Example:
# Application configuration
app_name "My App"
version 1.0
server {
host localhost
port 8080
}
features [auth api web]

The Philosophy Behind VIBE

Why your configuration's favorite feature might actually be a bug

The Problem

Arrays of objects in configuration files create hidden instability:

  • Index-based references break when items are reordered
  • Merging configurations becomes ambiguous and error-prone
  • Objects lack inherent identity beyond their position

The Solution

VIBE forbids arrays of objects, forcing you to use named entities:

  • Stable path-based references that never break
  • Clear, deterministic configuration merging
  • Identity baked into the structure itself

Good design is not just about the features you include; it's about the constraints you impose.

Read The Stability Paradox

Ready to Feel the VIBE?

Join developers who choose clarity over complexity

Full Specification Star on GitHub