{"id":50868103,"url":"https://github.com/vixcpp/ui","last_synced_at":"2026-06-15T03:07:26.571Z","repository":{"id":364761064,"uuid":"1210810458","full_name":"vixcpp/ui","owner":"vixcpp","description":"Web-first UI and app shell primitives for Vix.cpp applications.","archived":false,"fork":false,"pushed_at":"2026-06-14T11:07:03.000Z","size":65,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-14T12:18:24.476Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://docs.vixcpp.com/","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vixcpp.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-14T19:26:38.000Z","updated_at":"2026-06-14T11:07:07.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/vixcpp/ui","commit_stats":null,"previous_names":["vixcpp/ui"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/vixcpp/ui","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vixcpp%2Fui","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vixcpp%2Fui/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vixcpp%2Fui/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vixcpp%2Fui/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vixcpp","download_url":"https://codeload.github.com/vixcpp/ui/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vixcpp%2Fui/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34345667,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-15T02:00:07.085Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":[],"created_at":"2026-06-15T03:07:26.069Z","updated_at":"2026-06-15T03:07:26.566Z","avatar_url":"https://github.com/vixcpp.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Vix UI\n\nWeb-first UI and app shell primitives for Vix.cpp applications.\n\n`vix::ui` is a small UI foundation layer built on top of the Vix template engine.\nIt helps Vix.cpp applications describe views, render HTML responses, manage assets, build simple forms, and prepare future browser, desktop, and mobile app shells.\n\nIt is not a replacement for `vix::template_`.\nIt is a higher-level layer that makes template-based web UI development cleaner.\n\n## Goals\n\nVix UI starts with a simple direction:\n\n- keep Vix web-first\n- reuse the existing Vix template engine\n- provide small UI primitives\n- avoid a heavy frontend framework\n- prepare desktop/mobile shells without forcing native UI complexity early\n\nThe first target is server-rendered web UI.\n\nLater, the same web UI foundation can be used by desktop or mobile shells through WebView-based app containers.\n\n## What it provides\n\nCurrent primitives:\n\n- `vix::ui::View`\n- `vix::ui::ViewContext`\n- `vix::ui::ViewResult`\n- `vix::ui::Html`\n- `vix::ui::HtmlAttrs`\n- `vix::ui::HtmlEscape`\n- `vix::ui::HtmlResponse`\n- `vix::ui::Asset`\n- `vix::ui::AssetManifest`\n- `vix::ui::AssetManager`\n- `vix::ui::Field`\n- `vix::ui::Form`\n- `vix::ui::ValidationError`\n- `vix::ui::Platform`\n- `vix::ui::ShellConfig`\n- `vix::ui::AppShell`\n\n## Basic view example\n\n```cpp\n#include \u003ciostream\u003e\n#include \u003cmemory\u003e\n\n#include \u003cvix/template/Engine.hpp\u003e\n#include \u003cvix/template/StringLoader.hpp\u003e\n#include \u003cvix/ui/core/View.hpp\u003e\n\nint main()\n{\n  auto loader = std::make_shared\u003cvix::template_::StringLoader\u003e();\n\n  loader-\u003eset(\n      \"home.html\",\n      \"\u003ch1\u003eHello {{ name }}\u003c/h1\u003e\"\n      \"\u003cp\u003e{{ page_title }}\u003c/p\u003e\"\n  );\n\n  vix::template_::Engine engine(loader);\n\n  vix::ui::View view(\"home.html\");\n  view.set_title(\"Vix UI\");\n  view.set(\"name\", \"Gaspard\");\n\n  const vix::ui::ViewResult result = view.render(engine);\n\n  if (!result.success)\n  {\n    return 1;\n  }\n\n  std::cout \u003c\u003c result.output \u003c\u003c \"\\n\";\n  return 0;\n}\n```\n\n## HTML helpers\n\n```cpp\n#include \u003cvix/ui/html/Html.hpp\u003e\n#include \u003cvix/ui/html/HtmlAttrs.hpp\u003e\n\nvix::ui::HtmlAttrs attrs;\nattrs.set(\"class\", \"card\");\n\nstd::string html = vix::ui::Html::tag(\n    \"div\",\n    vix::ui::Html::text(\"Hello \u003cVix\u003e\"),\n    attrs\n);\n```\n\nOutput:\n\n```html\n\u003cdiv class=\"card\"\u003eHello \u0026lt;Vix\u0026gt;\u003c/div\u003e\n```\n\n## HTML response\n\n```cpp\n#include \u003cvix/ui/html/HtmlResponse.hpp\u003e\n\nvix::ui::HtmlResponse response = vix::ui::HtmlResponse::html(\"\u003ch1\u003eHello\u003c/h1\u003e\", 200);\n\nresponse.header_content_type(); // text/html; charset=utf-8\nresponse.body();                // \u003ch1\u003eHello\u003c/h1\u003e\nresponse.status_code();         // 200\n```\n\n`HtmlResponse` is transport-neutral.\nIt does not depend on a specific HTTP response type. Higher-level Vix integrations can copy its body, status and content type into a real HTTP response.\n\n## Assets\n\n```cpp\n#include \u003cvix/ui/assets/AssetManager.hpp\u003e\n\nvix::ui::AssetManager assets(\"/assets\");\n\nassets.add_stylesheet(\"app_css\", \"app.css\");\nassets.add_script(\"app_js\", \"app.js\", vix::ui::AssetLoading::Deferred);\nassets.add_font(\"inter\", \"fonts/inter.woff2\");\n\nstd::string html = assets.render();\n```\n\nExample output:\n\n```html\n\u003clink href=\"/assets/app.css\" media=\"all\" rel=\"stylesheet\" /\u003e\n\u003cscript defer src=\"/assets/app.js\"\u003e\u003c/script\u003e\n\u003clink\n  as=\"font\"\n  crossorigin=\"anonymous\"\n  href=\"/assets/fonts/inter.woff2\"\n  rel=\"preload\"\n/\u003e\n```\n\n## Forms\n\n```cpp\n#include \u003cvix/ui/forms/Form.hpp\u003e\n\nvix::ui::Form form = vix::ui::Form::post(\"/login\");\n\nform.add_email(\"email\");\nform.add_password(\"password\");\nform.add_hidden(\"_token\", \"abc123\");\n\nstd::string html = form.render();\n```\n\nValidation errors can be attached to the form and to individual fields:\n\n```cpp\nform.add_error(\"email\", \"Email is required.\");\n```\n\n## App shell\n\n`AppShell` is currently a lightweight shell descriptor.\n\nIt stores configuration, validates the shell settings, tracks running/stopped state, and exposes the effective target URL.\n\n```cpp\n#include \u003cvix/ui/shell/AppShell.hpp\u003e\n#include \u003cvix/ui/shell/ShellConfig.hpp\u003e\n\nvix::ui::ShellConfig config;\n\nconfig.set_name(\"Vix Admin\")\n      .set_title(\"Vix Admin\")\n      .set_host(\"127.0.0.1\")\n      .set_port(8080)\n      .set_width(1280)\n      .set_height(720);\n\nvix::ui::AppShell shell(config);\n\nauto result = shell.start();\n\nif (result.is_ok())\n{\n  // shell.running() == true\n}\n```\n\nNative desktop/mobile WebView startup can be added later on top of this public surface.\n\n## Module structure\n\n```txt\ninclude/vix/ui/\n  Version.hpp\n  all.hpp\n\n  core/\n    View.hpp\n    ViewData.hpp\n    ViewContext.hpp\n    ViewResult.hpp\n\n  html/\n    Html.hpp\n    HtmlResponse.hpp\n    HtmlAttrs.hpp\n    HtmlEscape.hpp\n\n  assets/\n    Asset.hpp\n    AssetManager.hpp\n    AssetManifest.hpp\n\n  forms/\n    Form.hpp\n    Field.hpp\n    ValidationError.hpp\n\n  shell/\n    AppShell.hpp\n    ShellConfig.hpp\n\n  platform/\n    Platform.hpp\n\n  support/\n    Error.hpp\n    Result.hpp\n```\n\n## Build\n\nFrom the repository root:\n\n```bash\nvix build\n```\n\nRun tests:\n\n```bash\nvix tests\n```\n\nRun examples:\n\n```bash\nvix run examples/01_basic_view.cpp\nvix run examples/02_html_response.cpp\nvix run examples/03_assets.cpp\n```\n\n## Design direction\n\nVix UI is intentionally small.\n\nThe template engine remains responsible for:\n\n- template loading\n- parsing\n- rendering\n- escaping\n- caching\n- includes\n- layouts\n- blocks\n\nThe UI module is responsible for:\n\n- view metadata\n- view contexts\n- HTML helpers\n- HTML response data\n- asset helpers\n- form helpers\n- platform/app shell primitives\n\nThis keeps the architecture simple and avoids building a heavy UI framework too early.\n\n## License\n\nMIT License.\n\nCopyright 2025, Gaspard Kirira.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvixcpp%2Fui","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvixcpp%2Fui","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvixcpp%2Fui/lists"}