Create blazing fast multithreaded Web Apps

Overview

Downloads Version License Chat PRs Welcome

Welcome to neo.mjs!

neo.mjs enables you to create scalable & high performant Apps using more than just one CPU, without the need to take care of a workers setup or the cross channel communication on your own.

Content

  1. Sponsors
  2. Scalable frontend architectures
  3. Multi Window COVID19 IN NUMBERS Demo App
  4. COVID19 IN NUMBERS Demo App
  5. What if ... (Short overview of the concept & design goals)
  6. Want to learn more?
  7. Impossible? Pick with caution!
  8. Online Examples
  9. Online Docs
  10. Command-Line Interface
  11. Ready to get started?
  12. Project History
  13. Story & Vision
  14. neo.mjs is in need of more contributors!
  15. neo.mjs is in need of more sponsors!
  16. Slack Channel for questions & feedback

Sponsors

Bronze Sponsors

Scalable frontend architectures

Multi Browser Window COVID19 IN NUMBERS Demo App

The most compelling way to introduce a new framework might simply be to show what you can do with it.

Blog post: Expanding Single Page Apps into multiple Browser Windows

Live Demo: COIN App (Multi Window)
Chrome (v83+), Edge, Firefox (Safari does not support SharedWorkers yet).
Desktop only.

Demo Video on YouTube:

You can find the code of the multi window covid app here.

COVID19 IN NUMBERS Demo App

Live Demo: COIN App dist/production
Desktop only => support for mobile devices is on the roadmap.

Demo Video on YouTube:

You can find the code of the covid app here.

Short overview of the concept & design goals

What if ... Benefit
1. ... a framework & all the apps you build are running inside a separate thread (web worker)? You get extreme Performance
2. ... the main thread would be mostly idle, only applying the real dom manipulations, so there are no background tasks slowing it down? You get extreme UI responsiveness
3. ... a framework was fully built on top of ES8, but can run inside multiple workers without any Javascript builds? Your development speed will increase
4. ... you don’t need source-maps to debug your code, since you do get the real code 1:1? You get a smoother Debugging Experience
5. ... you don’t have to use string based pseudo XML templates ever again? You get unreached simplicity, no more scoping nightmares
6. ... you don’t have to use any sort of templates at all, ever again? You gain full control!
7. ... you can use persistent JSON structures instead? You gain more simplicity
8. ... there is a custom virtual dom engine in place, which is so fast, that it will change your mind about the performance of web based user interfaces? You get extreme performance
9. ... the ES8 class system gets enhanced with a custom config system, making it easier to extend and work with config driven design patterns? Extensibility, a robust base for solid UI architectures
10. ... your user interfaces can truly scale? You get extreme Performance

Want to learn more?

neo.mjs Concepts

Impossible? Pick with caution!

blue or red pill

Still here? Welcome to neo.mjs - The webworkers driven UI framework

Online Examples

You can find a full list of (desktop based) online examples here:
Online Examples

You can pick between the 3 modes (development, dist/development, dist/production) for each one.

Online Docs

The Online Docs are also included inside the Online Examples.

dist/production does not support lazy loading the examples yet, but works in every browser:
Online Docs (dist/production)

The development mode only works on Chrome 80+, but does lazy load the example apps:
Online Docs (dev mode)

Hint: As soon as you create your own apps, you want to use the docs app locally,
since this will include the documentation for your own apps.

Command-Line Interface

You can run several build programs inside your terminal.
Please take a look at the Command-Line Interface Guide.

Ready to get started?

There are 3 different ways on how you can get the basics running locally.
Please take a look at the Getting Started Guide.

Project History

neo.mjs got released to the public on November 23, 2019.
Before this point, the project was already at 3720 commits.
Find out more about the start of it inside the Project History file.

Story & Vision

Although neo.mjs is ready to craft beautiful & blazing fast UIs,
the current state is just a fraction of a bigger picture.

Take a look at the Project Story and Vision.

neo.mjs is in need for more contributors!

Another way to fasten up the neo.mjs development speed is to actively jump in.
As the shiny "PRs welcome" badge suggests: open source is intended to be improved by anyone who is up for the challenge.

You can also write a guide in case you learned something new using neo.mjs or just help to get more eyes on this project.

Either way, here are more infos: Contributing

neo.mjs is in need for more sponsors!

Is the current code base useful for you or could it be in the future?
Do you like the neo.mjs concepts?
So far the development was made possible with burning all of my (tobiu's) personal savings.

This is obviously not sustainable, so to enable me to keep pushing like this, please support it.
The benefit of doing so is to get results delivered faster.

Here you go: Sponsors & Backers

Slack Channel for questions & feedback

There are some Javascript legends hiding in the shadows and waiting to be discovered.
Join our community: Slack Channel Invite Link

Build with ❤️ in Germany.



Copyright (c) 2015 - today, Tobias Uhlig & Rich Waters

Comments
  • Not opening in Safari

    Not opening in Safari

    Trying to open this link in Safari opens a blank page with error in the console: https://neomjs.github.io/pages/node_modules/neo.mjs/apps/sharedcovid/index.html#mainview=table SyntaxError: Unexpected identifier 'Neo'. import call expects exactly one argument.

    bug 
    opened by friksa 7
  • neo.mjs needs a logo

    neo.mjs needs a logo

    I am most definitely not a designer, so help on this one would be appreciated.

    I can someone comes up with a good idea, we can definitely add a backlink to a company page or linked in profile. Might be one of the easiest ways to show up as a project sponsor.

    ideas so far: Screenshot 2019-11-05 at 18 51 57 ( created with https://www.flamingtext.com/Name-Logos/Neo/ )

    Screenshot 2019-11-05 at 19 26 46

    help wanted 
    opened by tobiu 7
  • core.Base: state management using a modified getter

    core.Base: state management using a modified getter

    pondering ticket.

    instead of using the afterSetQueue, add a tmp. class prop to store the new config values object.

    then modify the autoGen getters to check for this object first and in case it does exist use it.

    instance.set() would then create this object, assign the values and delete it.

    goal: make all new values available inside the beforeGetXXX methods as well, although circular references there feel a bit ambiguous for the new value.

    a=1, b=2

    beforeSetA(val) {return val + this.b;}
    beforeSetB(val) {return val + this.a;}
    

    these 3 ways will create different outputs:

    inst.set({a:2, b:3});
    // a=5, b=5
    
    inst.a = 2;
    inst.b = 3; 
    // a = 4, b = 7
    
    inst.b = 3; 
    inst.a = 2;
    // a = 8, b = 6
    
    enhancement 
    opened by tobiu 6
  • Get listed on the gothinkster/realworld repo

    Get listed on the gothinkster/realworld repo

    Already applied on the project page 12 days ago, zero feedback: https://github.com/gothinkster/realworld/issues/446

    In case you would like to see the neo.mjs app there, please do add some weight to the linked ticket. After all, it is already feature complete for a while.

    I did already ping Thinkster on their FB page, but it had no effect.

    Screenshot 2019-12-09 at 22 33 51

    Thanks a lot for your support on this one!

    enhancement help wanted good first issue 
    opened by tobiu 6
  • Multi-window scope: adding support for re-opening an app

    Multi-window scope: adding support for re-opening an app

    Inside e.g. the shared covid dashboard, we can expand views like the helix into new browser windows.

    this does work fine for the first opening => we get a new app name and the theme map will store flags for added css files (delta updates). closing the helix and displaying it correctly works as well, since the original window already contains the required css.

    however, in case we expand the helix into a new window again (using the same app name), the css won't get added, since the flags inside the map are already set.

    we need a new algorithm to remove an app from the theme map and we should trigger it when destroying an app (inside the shared workers context).

    enhancement 
    opened by tobiu 5
  • Touch Support

    Touch Support

    Describe the bug The current implementation of touch support has the premiss that there is either touch support OR mouse support. My laptop has a touchscreen and still supports mouse.

    Because it is detected as touch support, it does not allow drag'n drop for the mouse.

    Desktop (please complete the following information):

    • OS: Windows 11
    • Browser chrome

    Additional context Possible solution:

    Detect if isMobile

    isMobile() {
        return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
    }
    

    If isMobile do not support mouse support. If !isMobile support touch AND mouse

    bug 
    opened by Dinkh 5
  • buildScripts/createClass

    buildScripts/createClass

    I want to create a convenience CLI program, which simplifies creating new neo classes.

    For the start, you should be able to pick between a base class of component.Base and container.Base.

    There will be follow-up tickets, like extending view models and controllers.

    enhancement 
    opened by tobiu 4
  • src/main/addon in workspace directory

    src/main/addon in workspace directory

    I would like to add a main thread addon to a project / app.

    Currently I have to add a new file to neoSrc.main.addon for some functioniality. It would be cool to be able to add this to appFolder.main.addon

    enhancement 
    opened by Dinkh 4
  • "Manager.mjs:384 Uncaught Error: Called sendMessage for a worker that does not exist: canvas" when trying samples

    Hey there,

    Was looking at trying this UI framework for a new app, and I'm trying to view some of the samples. Some work, but trying to navigate to "http://localhost:8080/apps/sharedcovidgallery/" yields, in the console:

    Manager.mjs:384 Uncaught Error: Called sendMessage for a worker that does not exist: canvas
        at Manager.sendMessage (Manager.mjs:384)
        at Manager.mjs:128
        at Array.forEach (<anonymous>)
        at Manager.broadcast (Manager.mjs:127)
        at DomEvents.mjs:403
        at Array.forEach (<anonymous>)
        at DomEvents.onBeforeUnload (DomEvents.mjs:402)
    sendMessage @ Manager.mjs:384
    (anonymous) @ Manager.mjs:128
    broadcast @ Manager.mjs:127
    (anonymous) @ DomEvents.mjs:403
    onBeforeUnload @ DomEvents.mjs:402
    Navigated to http://localhost:8080/apps/sharedcovidgallery/
    

    Steps to reproduce:

    dave@dave-macbook-pro failing-js % nvm use 16
    Now using node v16.9.1 (npm v7.21.1)
    dave@dave-macbook-pro failing-js % node --version
    v16.9.1
    dave@dave-macbook-pro failing-js % npm --version
    7.21.1
    dave@dave-macbook-pro failing-js % git clone -b main https://github.com/neomjs/neo.git
    Cloning into 'neo'...
    remote: Enumerating objects: 45776, done.
    remote: Counting objects: 100% (5077/5077), done.
    remote: Compressing objects: 100% (1565/1565), done.
    remote: Total 45776 (delta 3544), reused 4235 (delta 3424), pack-reused 40699
    Receiving objects: 100% (45776/45776), 19.69 MiB | 32.67 MiB/s, done.
    Resolving deltas: 100% (31976/31976), done.
    dave@dave-macbook-pro failing-js % cd neo 
    dave@dave-macbook-pro neo % git status
    On branch main
    Your branch is up to date with 'origin/main'.
    
    nothing to commit, working tree clean
    dave@dave-macbook-pro neo % npm i
    (...)
    
    dave@dave-macbook-pro neo % npm run build-all
    
    > [email protected] build-all
    > node ./buildScripts/buildAll.js -f -n
    (...)
    
    dave@dave-macbook-pro neo % npm run server-start
    
    > [email protected] server-start
    > webpack serve -c ./buildScripts/webpack/webpack.server.config.js --open
    
    <i> [webpack-dev-server] Project is running at:
    <i> [webpack-dev-server] Loopback: http://localhost:8080/
    <i> [webpack-dev-server] On Your Network (IPv4): http://192.168.1.159:8080/
    <i> [webpack-dev-server] On Your Network (IPv6): http://[fe80::1]:8080/
    <i> [webpack-dev-server] Content not from webpack is served from '/Users/dave/Projects/sandpit/failing-js/neo' directory
    <i> [webpack-dev-middleware] wait until bundle finished: /
    asset main.js 125 KiB [emitted] [minimized] (name: main) 1 related asset
    runtime modules 27.1 KiB 13 modules
    orphan modules 13.8 KiB [orphan] 7 modules
    cacheable modules 197 KiB
      modules by path ./node_modules/webpack-dev-server/client/ 50.8 KiB
        modules by path ./node_modules/webpack-dev-server/client/modules/ 30.2 KiB 2 modules
        3 modules
      modules by path ./node_modules/webpack/hot/*.js 4.3 KiB 4 modules
      modules by path ./node_modules/html-entities/lib/*.js 81.3 KiB 4 modules
      modules by path ./node_modules/url/ 37.4 KiB 3 modules
      modules by path ./node_modules/querystring/*.js 4.51 KiB 3 modules
      ./src/index.js 272 bytes [built] [code generated]
      ./node_modules/ansi-html-community/index.js 4.16 KiB [built] [code generated]
      ./node_modules/events/events.js 14.5 KiB [built] [code generated]
    webpack 5.53.0 compiled successfully in 1923 ms
    

    ...then navigating to http://localhost:8080/apps/sharedcovidgallery yields the above error.

    My guess is something to do with Chrome 93 is preventing workers from properly starting?

    opened by davewthompson 4
  • Add support for microfrontend mounting at runtime

    Add support for microfrontend mounting at runtime

    Is your feature request related to a problem? Please describe. We are developing our web based applications using the microfrontend design pattern. In practice we have developed a webpack suite that builds Jquery or React based mini-UIs into a well defined API. This API can then be used in other applications (currently tested with angular and reactjs environments) to mount those applications at runtime.

    It would be nice to know if neo.mjs supports such kind of pattern, this way one would be able to program components using React and embed those into neo.mjs using some kind of wrapper for managing the state inside neo.mjs

    enhancement 
    opened by dberardo-com 4
  • Project will not build on windows machines, nothing in dist folder

    Project will not build on windows machines, nothing in dist folder

    Describe the bug There is no working build on windows machines.

    To Reproduce Steps to reproduce the behavior:

    1. Checkout the project
    2. do npm run install
    3. do npm run build-all
    4. do npm run server-start

    Expected behavior The project builds correctly with all the code and CSS

    Desktop (please complete the following information):

    • OS: Windows 10
    • Browser: Chrome
    • Version: 85 (latest/any)

    Additional context Windows has specific path resolving issues that are not addressed

    bug 
    opened by ndagovic 4
  • We need a way to make a buffered function call.

    We need a way to make a buffered function call.

    We need a Neo.Function.createBuffered() or Neo.Function.debounce() https://css-tricks.com/debouncing-throttling-explained-examples/

    Here's the lodash source. It's MIT, and if MIT is good for Neo I'd just copy their implementation, or make it easy to simply integrate lodash into the app worker.

    https://github.com/lodash/lodash/blob/4.17.15/lodash.js#L10304

    enhancement 
    opened by maxrahder 2
  • form.field.Select: editable_

    form.field.Select: editable_

    setting the config to true should disable typing into the field.

    instead, the entire field should get a cursor: pointer and clicking the field should open the list.

    enhancement 
    opened by tobiu 0
  • component.Toast: multi window support

    component.Toast: multi window support

    we need to add a running config for each appName.

    manager.Component: updateItemsInPosition() needs to fetch the domRects for each realm. please use Promise.all() for this one.

    enhancement 
    opened by tobiu 0
  • HighlightJS resources

    HighlightJS resources

    right now, we have the resources twice inside the repo, which is not good for maintenance and package file size.

    the current approach breaks inside the dist modes: Screenshot 2023-01-04 at 21 28 48

    since the top level resources folder does get copied into dist already, we should move the files there.

    @Dinkh

    bug 
    opened by tobiu 0
  • Themes should optionally only need colors

    Themes should optionally only need colors

    I would like to be able to only add a style.scss with colors being merged with light and dark. To be able to use it, there should be a preset file.

    Whatever item you leave blank, will be taken from the parent-theme.

    style.scss

        'base-theme': 'theme-light',
    
        'button-active-background-color'  : #ddd,
        'button-active-border-color'    : #1c60a0,
        'button-active-color'             : #1c60a0,
        'button-background-color'         : #fff,
        'button-background-image'         : none,
        'button-background-gradient-end'  : #323536,
        'button-background-gradient-start': #434749,
        'button-badge-background-color'   : #1c60a0,
        'button-badge-color'              : #fff,
        'button-badge-margin-left'        : -10px,
        'button-badge-margin-top'         : -10px,
       ...
    
    enhancement 
    opened by Dinkh 1
Releases(4.6.6)
  • 4.6.6(Jan 6, 2023)

  • 4.6.5(Jan 6, 2023)

  • 4.6.4(Jan 6, 2023)

  • 4.6.3(Jan 5, 2023)

    form.field.Text

    • disabled state vars
    • border-radius for labelPosition: inline
    • floating label top adjustment based on the border-width
    • position-inline: left border area scales with the border width

    you can now adjust fields to your needs. some examples (not recommended from a design perspective, but possible)

    Screenshot 2023-01-05 at 21 22 05 Screenshot 2023-01-05 at 21 21 58 Screenshot 2023-01-05 at 20 51 46 Screenshot 2023-01-05 at 20 51 41

    collection.Base: fix for an edge case where clearing the filters broke

    Source code(tar.gz)
    Source code(zip)
  • 4.6.2(Jan 5, 2023)

  • 4.6.1(Jan 4, 2023)

  • 4.6.0(Jan 4, 2023)

    A massive amount of code changes. see: https://github.com/neomjs/neo/pull/3770/files

    In theory, adding the baseCls should not break anything. you can shorten quite a lot of custom cls definitions, since the base selectors are no longer needed.

    you can override baseCls though, in case you want to remove basic selectors.

    also see: https://github.com/neomjs/neo/issues/3767

    Source code(tar.gz)
    Source code(zip)
  • 4.4.19(Jan 4, 2023)

  • 4.4.18(Jan 3, 2023)

    while rendering the picker into the field element itself was charming for a simplified focus management, getting the positions right was getting more and more complex, in case e.g. relative positioned parents did show up.

    it was time to make use of the powerful focus manager.

    Source code(tar.gz)
    Source code(zip)
  • 4.4.17(Jan 3, 2023)

  • 4.4.16(Jan 3, 2023)

  • 4.4.15(Jan 1, 2023)

    Debugging Features:

    Neo.first(componentDescription, returnFirstMatch)

                // as String: ntype[comma separated propterties]
                Neo.first('toolbar button[text=Try me,icon=people]')
                // as Object: Add properties. ntype is optional
                Neo.first({
                    icon: 'people'
                })
                // as Array: An Array of Objects. No Strings allowed
                Neo.first([{
                    ntype: 'toolbar'
                },{
                    ntype: 'button', text: 'Try me', icon: 'people
                }])
    
                // return all fields in the application
                Neo.first('basefield', false)
    

    Neo.manager.Component.down Component.down can now search for all prototype ntypes, so that you can define your own ntype, but still find the original ntype.

               // find numberfield by searching for basefield
               Neo.first('basefield[name=addressnumber]')
    

    GoogleMaps

    updated and extended the example

    Source code(tar.gz)
    Source code(zip)
  • 4.4.14(Dec 28, 2022)

  • 4.4.13(Dec 28, 2022)

  • 4.4.12(Dec 28, 2022)

  • 4.4.11(Dec 28, 2022)

  • 4.4.10(Dec 28, 2022)

    • markerStore
    • markerStoreConfig
    • automatically adding markers onStoreLoad()
    • manager.Component: getParents() => optionally passing a component id instead of a reference
    • container.Base: createItem() => deleting an itemDefaults ntype in case a module was passed and vice versa
    Source code(tar.gz)
    Source code(zip)
  • 4.4.8(Dec 21, 2022)

  • 4.4.7(Dec 21, 2022)

  • 4.4.5(Dec 21, 2022)

    1. form.field.Text now subscribes to mouseenter and mouseleave events
    2. new scss variables for hovered border color and outline
    3. form.field.Trigger now uses the same border width as textfields
    4. form.field.Trigger is now using display: flex with centered items to honor different field heights
    Source code(tar.gz)
    Source code(zip)
  • 4.4.4(Dec 21, 2022)

    1. polished the logic for getActiveIndex() and getHeaderlessActiveIndex()
    2. in case headerlessActiveIndex is set before the store got loaded, apply the initial selection
    Source code(tar.gz)
    Source code(zip)
  • 4.4.3(Dec 21, 2022)

  • 4.4.1(Dec 20, 2022)

    1. list.Base: activeIndex: a convenience shortcut to change the selected item. we can bind this config inside view models
    2. form.field.Text: textfield-border-width scss var
    3. form.field.Text: textfield-outline-active scss var
    Source code(tar.gz)
    Source code(zip)
  • 4.4.0(Dec 20, 2022)

    While view models (model.component) are limited to components, we can also now use bindings directly into layouts.

    A nice example (which is needed for a current client project):

    layout: {ntype: 'card', bind: activeIndex: data => data.activeIndex}}

    This allows us to change the index of a container layout whenever a view model data property (state variable) changes.

    Source code(tar.gz)
    Source code(zip)
  • 4.3.34(Dec 19, 2022)

Owner
neo.mjs
collection of all neo.mjs related repositories
neo.mjs
A Web Component compiler for building fast, reusable UI components and static site generated Progressive Web Apps

Stencil: A Compiler for Web Components and PWAs npm init stencil Stencil is a simple compiler for generating Web Components and static site generated

Ionic 11.3k Jan 4, 2023
AngularJS - HTML enhanced for web apps!

AngularJS AngularJS lets you write client-side web applications as if you had a smarter browser. It lets you use good old HTML (or HAML, Jade/Pug and

Angular 59.3k Jan 1, 2023
Cybernetically enhanced web apps

What is Svelte? Svelte is a new way to build web applications. It's a compiler that takes your declarative components and converts them into efficient

Svelte 64.3k Dec 31, 2022
Dojo Framework. A Progressive Framework for Modern Web Apps

@dojo/framework Dojo is a progressive framework for modern web applications built with TypeScript. Visit us at dojo.io for documentation, tutorials, c

Dojo 549 Dec 25, 2022
🙋‍♀️ 3kb library for tiny web apps

3kb library for tiny web apps. Sometimes, all you want to do is to try and do something—No boilerplate, bundlers, or complex build processes. Lucia ai

Aiden Bai 699 Dec 27, 2022
A declarative, HTML-based language that makes building web apps fun

A declarative, HTML-based language that makes building web apps fun ?? Docs ∙ Try Online ∙ Contribute ∙ Get Support Intro Marko is HTML re-imagined as

Marko 12k Jan 3, 2023
The simplest way to create web components from plain objects and pure functions! 💯

?? One of the four nominated projects to the "Breakthrough of the year" category of Open Source Award in 2019 hybrids is a UI library for creating web

hybrids 2.7k Dec 27, 2022
⚛️ Fast 3kB React alternative with the same modern API. Components & Virtual DOM.

Fast 3kB alternative to React with the same modern API. All the power of Virtual DOM components, without the overhead: Familiar React API & patterns:

Preact 33.6k Jan 8, 2023
:fire: An extremely fast, React-like JavaScript library for building modern user interfaces

Inferno is an insanely fast, React-like library for building high-performance user interfaces on both the client and server. Description The main obje

Inferno 15.6k Dec 31, 2022
🌙 The minimal & fast library for functional user interfaces

Moon The minimal & fast library for functional user interfaces Summary ?? Small file size (2kb minified + gzip) ⚡ Blazing fast view rendering ?? Purel

Kabir Shah 6k Jan 2, 2023
Knockout makes it easier to create rich, responsive UIs with JavaScript

Knockout Knockout is a JavaScript MVVM (a modern variant of MVC) library that makes it easier to create rich, desktop-like user interfaces with JavaSc

Knockout.js 10.3k Dec 31, 2022
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

Supporting Vue.js Vue.js is an MIT-licensed open source project with its ongoing development made possible entirely by the support of these awesome ba

vuejs 201.6k Jan 7, 2023
Ember.js - A JavaScript framework for creating ambitious web applications

Ember.js is a JavaScript framework that greatly reduces the time, effort and resources needed to build any web application. It is focused on making yo

Ember.js 22.4k Jan 4, 2023
Our original Web Component library.

Polymer ℹ️ Note: This is the current stable version of the Polymer library. At Google I/O 2018 we announced a new Web Component base class, LitElement

Polymer Project 21.9k Jan 3, 2023
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

vue-next This is the repository for Vue 3.0. Quickstart Via CDN: <script src="https://unpkg.com/vue@next"></script> In-browser playground on Codepen S

vuejs 34.6k Jan 4, 2023
OpenUI5 lets you build enterprise-ready web applications, responsive to all devices, running on almost any browser of your choice.

OpenUI5. Build Once. Run on any device. What is it? OpenUI5 lets you build enterprise-ready web applications, responsive to all devices, running on al

SAP 2.7k Dec 31, 2022
The AMP web component framework.

AMP ⚡ ⚡ ⚡ ⚡ Metrics Tooling AMP is a web component framework for easily creating user-first websites, stories, ads, emails and more. AMP is an open so

AMP 14.9k Jan 4, 2023
WinBox is a professional HTML5 window manager for the web: lightweight, outstanding performance, no dependencies, fully customizable, open source!

WinBox is a professional HTML5 window manager for the web: lightweight, outstanding performance, no dependencies, fully customizable, open source!

Nextapps GmbH 5.7k Jan 3, 2023