{"id":29717764,"url":"https://github.com/thisisignitedoreo/wkv","last_synced_at":"2026-02-08T15:31:38.430Z","repository":{"id":300850041,"uuid":"1007375757","full_name":"thisisignitedoreo/wkv","owner":"thisisignitedoreo","description":"A rough approximation of what a key-value config should've looked like","archived":false,"fork":false,"pushed_at":"2025-06-24T11:29:32.000Z","size":220,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-07-24T10:08:00.358Z","etag":null,"topics":["diy","markup-language","simplicity"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thisisignitedoreo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-23T22:41:04.000Z","updated_at":"2025-06-24T11:29:36.000Z","dependencies_parsed_at":"2025-06-23T23:41:22.728Z","dependency_job_id":null,"html_url":"https://github.com/thisisignitedoreo/wkv","commit_stats":null,"previous_names":["thisisignitedoreo/wkv"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/thisisignitedoreo/wkv","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thisisignitedoreo%2Fwkv","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thisisignitedoreo%2Fwkv/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thisisignitedoreo%2Fwkv/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thisisignitedoreo%2Fwkv/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thisisignitedoreo","download_url":"https://codeload.github.com/thisisignitedoreo/wkv/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thisisignitedoreo%2Fwkv/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29235226,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-08T14:18:14.570Z","status":"ssl_error","status_checked_at":"2026-02-08T14:18:14.071Z","response_time":57,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["diy","markup-language","simplicity"],"created_at":"2025-07-24T08:16:59.450Z","updated_at":"2026-02-08T15:31:38.412Z","avatar_url":"https://github.com/thisisignitedoreo.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"\n\u003cimg alt=\"wkv logo\" src=\"icon-shadow.png\" width=256 height=256\u003e\n\n# wkv\nwkv - a rough approximation of what a key-value config should've looked like.\n\n## What?\nwkv is a key-value data storage format designed to be fast and simple. No more,\nno less.\n\nwkv stands for Whatever Key-Values.\n\n## But... where is all the code?\nLMAO, where do you think it is?\n\nOn a more serious note, you write it. The format is really simple and does not\nhave _any_ specification. And that is intentional: it is really easy to add a\nwhole bunch of features for the format to fit all the use cases. But... why?\nIsn't it easier for you to actually go and implement all the features you need?\nThat is the philosophy behind wkv. The philosophy is such that there isn't a\nphilosophy. You do what you want, based, pretty roughly, on what is written\nhere. It can be as simple or as complex as you want, ranging from a single C\nloop with a few branch cases to a whole Python module. You need datetime?\nGo ahead, implement that. You need HEX colors? Go ahead, it's that simple.\n\n## Base case\nAt the _very_ base case wkv looks like this:\n```\nkey=Value\nKey is any sequence of bytes=Value is too.\n```\nAnd that is it. Anything more complex, and you are on your own. Do you want\nescaped strings? Implement them:\n```\nkey=\"Here's a newline -\u003e \\n\"\n```\nNeed a binary blob? Go ahead:\n```\nkey=b26Here's another newline -\u003e\n\nanother_one=sHere's an unescaped string\n```\nThe concept is that everything is a single type - **data**. The assumptions you\nmake about it transform it into different types. Do you want to infer the types\nfrom the definitions? Go ahead. You don't? Well, you don't. It's _that_ simple.\n\n## This looks stupid. Don't we already have JSON, YAML, TOML, \u0026lt;insert your favourite markup language here\u0026gt;?\n\nYup, we certainly do. The problem is: they are all really complex. You need\nwhole libraries just to parse and serialize them. Yes, sometimes this complexity\nis needed, e.g. for trees or something... But you most certainly do not need to\nwrite a tree when you are trying to save a savestate of your application to the\ndisk. Most of the time you need a simple key-value storage. And that is it.\n\nWell, what if you really want trees? Go ahead, implement them in wkv. And no one\nwill say anything about best practices and unadhering to the spec, because the\nspec _does not exist_. You do whatever, as the name suggests.\n\n## But what about \u0026lt;a common data type\u0026gt;?\nYou want booleans? Go ahead, prefix notation allows really easily to define them\nas `t` and `f` (gives you those lisp vibes, yeah?). Null? `n`. A float number?\nYou could define it as a standard floating point literal from C, but that\nrequires a lot of machinery. What about `f1.2`? Or, maybe, implement all this\ntricky machinery. The limit is your imagination.\n\nI've already gone through the trouble of figuring most of these out, so, here's\na (kinda) comprehensive list of common data types:\n- `[-]12`: a number, consisting only of digits. Optionally signed, with a minus in\n  front of it.\n- `s\u003cdata\u003e\\n`: a string, consisting of any data, unescaped, excluding the newline\n- `\"\u003cstring\u003e\"`: a quoted string, optionally escaped\n- `b\u003clength\u003e\u003cexactly length bytes\u003e`: a blob of opaque sequence of bytes\n- `f12[.34][e56]`: a floating point literal\n- `t`, `f`: booleans\n- `n`: a null type\n\nThey are designed so it is real easy to parse them just by checking from what\ncharachter they start from, so your little loop does not have to go through the\nlong tropes of parsing the values.\n\n## I want arrays!\nArrays are simple. They are merely a length + a stride of keys.\n\nExample:\n\n```\nimages.len=10\nimages.0=b1024\u003cdata\u003e\nimages.1=b1024\u003cdata\u003e\n...\nimages.9=b1024\u003cdata\u003e\n```\n\nOr maybe underscore instead of the dot? Or maybe a snowman emoji? Or maybe you\nthink it would be easier to parse if you added indices to it in a form of a uint\nbinary number? Or maybe store a length and an array as another key-value that\nevaluates to an array for the compression of the file size? Again, your\ncreativity is your friend.\n\n## Where do I even start?\nUsually, wkv is implemented in a single loop with a few branching ifs.\n\nWant examples?\n\n```c\n// Yes, this does use some abstract data structures. Technically, it is\n// pseudocode, go cry about it, that's just an example. It should be relatively\n// easy to implement this with only C's stdlib, but I also am a lazy person.\n// That implementation is left as an exercise for the reader. ;)\n\n/// Returns true on failure.\nbool parse_config(FILE *f, struct Config *conf) {\n    while (!feof(f) \u0026\u0026 !ferror(f)) {\n        String value = file_read_until(f, \"\\n\");\n\tString key = string_split(\u0026value, SV(\"=\"));\n\tif (string_equal(key, SV(\"option1\"))) conf-\u003eoption1 = string_parse_int(value);\n\telse if (string_equal(key, SV(\"option2\"))) conf-\u003eoption2 = value;\n\telse return true;\n    }\n    return false;\n}\n```\n\n```python\n# A simple example\ndef parse_config(config):\n    result = {}\n    for i in config.split(\"\\n\"):\n    \tkey, value = i.split(\"=\")\n        result[key] = value\n    return result\n\n# A more sophisticated one\n# This one needs a lot more error checking, but it's probably okay for an\n# example.\ndef parse_a_hard_config(config):\n    result = {}\n    cur = 0\n    anchor = 0\n    while cur \u003c len(config):\n    \twhile config[cur] != \"=\": cur += 1\n\tkey = config[anchor:cur]\n\tcur += 1  # Skip the `=`\n\tvalue = None\n\tif config[cur] == 's':\n\t    anchor = cur + 1\n\t    while config[cur] != \"\\n\": cur += 1\n\t    value = config[anchor:cur]\n\telif config[cur] == 'b':\n\t    anchor = cur + 1\n\t    cur += 1\n\t    while config[cur] in string.digits: cur += 1\n\t    length = int(config[anchor:cur])\n\t    anchor = cur\n\t    cur += length\n\t    value = config[anchor:cur]\n\telif config[cur] == 't': value = True\n\telif config[cur] == 'f': value = False\n\telse: raise Exception('the parser shit the bed')\n\tresult[key] = value\n    return result\n```\n\nYes, some of the examples lack error checking. But what if you parse only\nmachine-generated config that is always generated right? Well, you are certainly\nlying to me, nothing the machine generates is right. But okay, suppose it\ndoesn't need as thorough of error checking as user input. Well, then don't\nimplement any of it! It's that simple.\n\nWhat if you really want to change something in the format? Maybe you want to\nswap the equals separator to the snowman emoji? Go ahead. This is not a format,\nthis is a rough approximation of a good config format. Or a savestate format. Or\na ... you get the point. If you really want you can even store an image as wkv,\nmaybe like this?\n```\nchannels=4\nwidth=1024\nheight=1024\ndata=b4194304{ raw image data }\n```\nAs inefficient as this is, it is quite funny.\n\n## This is really cool! What about licensing though?\nHaha, what? **You** define the format in **your** code, write **your own**\nparser... As far as I am concerned the thing you took from me is the mere idea,\nand licensing concepts so far hasn't been a great idea. :^)\n\nAnyway, feel free to use this README for anything. For making real\nproduction-grade stuff, for hackernews praising for how simple this is and how\nwe do not need any more complexity and for hackernews raging for how simple this\nis and how we need more complexity.\n\n---\n\n## r/programming chaos\nOkay, I did not expect people to rage as much as they were over the fact that\nyou actually have to write code for this one. Like, who are you? _A programmer?_\nNo shit this isn't interoperable - I am not going to put this format into a\nREST API, I am parsing some user data and some savestates with this. That is it. If this\nmakes your blood boil - I think I did a very well job here. Actually, the more people rage\n\\- the more I think I've honestly struct gold. For all the programmers reading this\n\\- have fun implmeneting this, for all the \"programmers\" - I do not want you to\nget your diaper messy, go ahead and rage about this on some forums. \u0026gt;:)\n\nSeriously, the fact that REAL people that program FOR MONEY wrote this in the comments\nhonestly makes me want to get replaced by AI.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthisisignitedoreo%2Fwkv","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthisisignitedoreo%2Fwkv","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthisisignitedoreo%2Fwkv/lists"}