{"id":19142115,"url":"https://github.com/eldoy/brage","last_synced_at":"2026-06-14T01:31:49.079Z","repository":{"id":139867317,"uuid":"139562067","full_name":"eldoy/brage","owner":"eldoy","description":"Javascript component library concept for single page applications","archived":false,"fork":false,"pushed_at":"2018-07-22T20:10:55.000Z","size":2331,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-08-23T04:01:35.012Z","etag":null,"topics":["dom","javascript","library-free","minimal","tiny"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/eldoy.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":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-07-03T09:44:57.000Z","updated_at":"2022-06-04T21:55:31.000Z","dependencies_parsed_at":null,"dependency_job_id":"8543fdef-562c-4d94-b3b3-b747d54e9b61","html_url":"https://github.com/eldoy/brage","commit_stats":null,"previous_names":["fugroup/brage"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/eldoy/brage","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eldoy%2Fbrage","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eldoy%2Fbrage/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eldoy%2Fbrage/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eldoy%2Fbrage/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eldoy","download_url":"https://codeload.github.com/eldoy/brage/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eldoy%2Fbrage/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34306772,"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-13T02:00:06.617Z","response_time":62,"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":["dom","javascript","library-free","minimal","tiny"],"created_at":"2024-11-09T07:25:55.607Z","updated_at":"2026-06-14T01:31:49.063Z","avatar_url":"https://github.com/eldoy.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Brage.js\n\nConcept Javascript component library for single page web applications. Very minimal, only 150 lines of code, no dependencies, just plain vanilla Javascript (ES6). Does not use a virtual DOM, updates must be done by calling render when your data updates.\n\nIncludes complete webpack setup and tests. Enjoy!\n\n### INSTALLATION\n\n```npm i brage```\n\nYou can also just include the javascript file found in ```dist/brage.js``` in your HTML file.\n\n### USAGE\n\nFrom within your application views or components do for example ```import { div, a, p, input } from 'brage'``` to include the div, a, p and input tags.\n\nTo run the example application, clone the repo, and do ```npm install``` then ```npm run dev```. The live server should start automatically in your browser at ```http://localhost:8080```. Hot code reloading included out of the box.\n\nStart the tests with ```npm run test```. Testing brage views is super easy with Jest or JSDOM as everything is just a function.\n\n```javascript\n// This is what it looks like\n\nsection(\n  h1('Brage.js is so easy'),\n  p('This is how you use it'),\n  ul({ class: 'list' },\n    li('Steak'),\n    li('Milk'),\n    li('Eggs'),\n    li('Liver')\n  ),\n  aside('Cool?')\n)\n```\n\n### API\nEvery element has access to its parent through the ```parent``` property.\n\n```javascript\n// Access the parent\nlet world\nconst list = ul(\n  li('Hello'),\n  world = li('World')\n)\nworld.parent === list // true\n```\n\nThe Brage DOM methods makes it easy to manipulate the DOM, but you can also just use the standard DOM methods included in all browsers. All Brage tag elements are just normal HTMLElements.\n\n#### Mount\n```javascript\n// Mount list into body\nconst list = ul(li('Hello'), li('World'))\nmount(list)\n\n// Mount list into another tag\nmount(list, document.querySelector('#app'))\n```\n#### Append\n```javascript\n// Append paragraph to body\nconst paragraph = p('Hello world')\nappend(paragraph)\n\n// Append paragraph to another element\nappend(paragraph, document.querySelector('#app'))\n```\n\n#### Insert\n```javascript\n\n// Insert a new paragraph before the .paragraph element\ninsert(p('New'), document.querySelector('.paragraph'))\n```\n\n#### Replace\n```javascript\n// Replace a paragraph with another paragaph\nreplace(p('New'), document.querySelector('.paragraph'))\n```\n\n### VIEWS\n\nThe views are the components of Brage. They should be a class or a function instance that has a render function.\n\n```javascript\nimport { div, h1, p, img } from '@/modules/brage.js'\nimport banner from '@/assets/images/brage.jpg'\n\nclass HomeView {\n  render = () =\u003e {\n    return(\n      div(\n        h1('Home'),\n        p('Welcome to our Brage.js demo page!'),\n        div(\n          img({ src: banner })\n        )\n      )\n    )\n  }\n}\n\nexport default new HomeView()\n```\n\nImport the view in another file with\n```javascript\nimport homeView from '@/views/site/home-view.js'\n```\n\n### ROUTER\n\nBrage comes with a router for your pages.\n\n```javascript\n// The view is a class that contains a render function.\n\nimport { BrageRouter } from 'brage'\nimport homeView from '@/views/site/home-view.js'\nimport aboutView from '@/views/site/about-view.js'\nimport listView from '@/views/site/list-view.js'\nimport controllerView from '@/views/site/controller-view.js'\nimport todoView from '@/views/todo/todo-view.js'\n\nconst routes = [\n  { path: '/', view: homeView },\n  { path: '/about', view: aboutView },\n  { path: '/list/:message', view: listView },\n  { path: '/controller', view: controllerView },\n  { path: '/todo', view: todoView }\n]\n\nexport default new BrageRouter(routes)\n```\n\nTo add a route, use the ```router-link``` class for your link:\n```javascript\nimport { header, nav, a, div } from '@/modules/brage.js'\nimport routes from '@/lib/routes.js'\n\nclass HeaderView {\n  render = () =\u003e {\n    const view = (\n      header(\n        nav(\n          // Add the router-link class to each router link\n          this.homeLink = a('Home', { class: 'router-link active', href: '/' }),\n          this.aboutLink = a('About', { class: 'router-link', href: '/about' }),\n          this.listLink = a('List', { class: 'router-link', href: '/list/hello' }),\n          this.controllerLink = a('Controller', { class: 'router-link', href: '/controller' }),\n          this.todoLink = a('Todo', { class: 'router-link', href: '/todo' })\n        )\n      )\n    )\n\n    // Call registerLinks for each link you want to use with the router\n    routes.registerLinks([\n      this.homeLink,\n      this.aboutLink,\n      this.listLink,\n      this.controllerLink,\n      this.todoLink\n    ])\n\n    return view\n  }\n}\n\nexport default new HeaderView()\n\n```\n\nAdd a ```:``` to you link parts to make your link paths dynamic. ```/users/:id``` will match the link ```/users/1234``` and will give you a props object sent to the ```render``` function in your view that looks like this:\n```javascript\n// Route props are sent to the render function\nrender = (props) =\u003e {\n  console.log(props) // { id: '1234' }\n}\n\n// Use destructuring to capture the props directly\nrender = ({ id }) =\u003e {\n  console.log(id) // '1234'\n}\n```\n\n### TAGS\nAll HTML5 tags are supported. If you want to make your own tags for Web Components or similar, use ```t('tagname')``` instead.\n\nUse ```fragment``` if you want to create a document fragment without any tag output.\n\na,\nabbr,\naddress,\narea,\narticle,\naside,\naudio,\nb,\nbase,\nbdi,\nbdo,\nblockquote,\nbody,\nbr,\nbutton,\ncanvas,\ncaption,\ncite,\ncode,\ncol,\ncolgroup,\ncommand,\ndatalist,\ndd,\ndel,\ndetails,\ndfn,\ndiv,\ndl,\ndt,\nem,\nembed,\nfieldset,\nfigcaption,\nfigure,\nfooter,\nform,\nfragment,\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\nhead,\nheader,\nhgroup,\nhr,\nhtml,\ni,\niframe,\nimg,\ninput,\nins,\nkbd,\nkeygen,\nlabel,\nlegend,\nli,\nlink,\nmain,\nmap,\nmark,\nmenu,\nmeta,\nmeter,\nnav,\nnoscript,\nobject,\nol,\noptgroup,\noption,\noutput,\np,\nparam,\npre,\nprogress,\nq,\nrp,\nrt,\nruby,\ns,\nsamp,\nscript,\nsection,\nselect,\nsmall,\nsource,\nspan,\nstrong,\nstyle,\nsub,\nsummary,\nsup,\ntable,\ntbody,\ntd,\ntemplate,\ntextarea,\ntfoot,\nth,\nthead,\ntime,\ntitle,\ntr,\ntrack,\nunderline,\nul,\n_var,\nvideo,\nwbr\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feldoy%2Fbrage","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feldoy%2Fbrage","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feldoy%2Fbrage/lists"}