Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use-cases #143

Open
cztomsik opened this issue Mar 2, 2020 · 22 comments
Open

Use-cases #143

cztomsik opened this issue Mar 2, 2020 · 22 comments

Comments

@cztomsik
Copy link
Owner

cztomsik commented Mar 2, 2020

I'd like to know what you want to build with this project.

It will help me with some future design decisions and it's also going to be very useful when writing documentation (better examples).

@knoopx
Copy link

knoopx commented Mar 3, 2020

Hey @cztomsik, I would like to build an RPI touchscreen client for octoprint/klipper. I'm also very interested in your hackable tv project

@cztomsik
Copy link
Owner Author

cztomsik commented Mar 4, 2020

hey, thanks for the feedback and good luck with the project - I think it's actually very cool idea. Feel free to reach me on discord if you're stuck with something :)

@egasimus
Copy link

All I want is to be able to put semantic graphics on screen easily, cheaply and flexibly. The current platform fragmentation is insane: browsers are everywhere and generally pleasant to develop for but are terrible resource hogs and a source of security vulnerabilities; while native toolkits are either too low-level or tend to have too many assumptions for me to work comfortably with. A non-browser-based, DOM-like thing would be a game-changer.

@cztomsik
Copy link
Owner Author

@egasimus thanks for your response, I'm glad it's not just me :-)

@egasimus @knoopx
I still need to finish few things before release but I want to write some tutorials soon, is there anything you'd like to see in particular?

@egasimus
Copy link

@cztomsik Idk, but if you already have some topics in mind I could try and lend a hand with writing some tutorials?

@cztomsik
Copy link
Owner Author

@egasimus I need to polish public API (window creation & context isolation) a bit first but then it would be really helpful.

Some ideas:

  • hello world, todomvc, contacts-app, etc. (simple examples for beginners)
  • twitter client
  • trello desktop app (incl. drag-drop)
  • markdown editor (I already have something but it's not yet ready)
  • terminal app
  • image optimizer
  • cache cleaner/disk space seeker (find what's using the space & make it easy to delete it)
  • slack/discord app (here's really old PoC https://github.com/cztomsik/slack-app)
  • audio manager/convertor (I've bought a lot of music on iTunes)
  • ssh/kubernetes port forwarding (something like https://www.electronjs.org/apps/kube-forwarder)
  • docker manager (something like portainer or kitematic)

I could even provide some PoCs of those so you wouldn't need to start from scratch. But it would be best to discuss it on discord. (join link is on the homepage)

@egasimus
Copy link

Discord is... suboptimal. In general, I prefer asynchronous conversations (like this one), but as far as modern collaboration tools go, why not give Riot a shot? :-)

I have some neat ideas about audio library management in particular so I might go with that. Terminal multiplexing, desktop panels, and a discoverable systemd GUI are some other interesting problem spaces - a little more niche but fun and useful nonetheless.

Feature-wise, if Graffiti supports a canvas-like component, or some sort of OpenGL/Vulkan rendering surface (does it? guess I should start reading the source huh), I'd build a trading chart visualizer. Or a music sequencer. Or an image editor of course. Actually for those first two I might be able to dig out some code based on canvas and/or SVG (and at least one demo with pure Rust+GLSL) that I could look into porting/rewriting for Graffiti.

So yeah, what about people interested in porting their existing apps? Maybe if you had some sort of medium-sized React app that doesn't work in Graffiti out of the box but could be ported with a modicum of effort, I could do a writeup of the steps to get it running, maybe even do a comparative benchmark to measure exactly how much faster than a browser this is.

Sounds like fun, I'm really glad to be discussing this :-)

@cztomsik
Copy link
Owner Author

cztomsik commented Apr 1, 2020

@egasimus np, we can stay here or you can mail me

audio-project sounds very interesting but

  • there's no Audio api, you'd need to find some nodejs module (I've seen at least one)
  • webgl is not available right now but I definitely want to do that, and I want canvas and SVG too (maybe, I haven't tried yet, it might be possible to use raub-webgl with some changes)

Currently, the biggest limitation is the absence of global styles (only inline styles are supported). I'd like to avoid adding it because it would take months to make it work similarly - I'd rather like to add support for some utility-first CSS framework, like tailwind or tachyons - that could be done easily with plain react (custom h function would just concatenate & cache the inline style)

// this does not exists yet, but it's simple to do, actually
/* @jsx h */
import { h } from 'inline-tachyons'

<div cx="btn p-5">Btn with padding 5</div>

And I also think, CSS is fundamentally broken - it's so easy to get into collisions and what's worse, css rules are applied in the definition order (order of classes in className does not matter) and I'd like to avoid repeating the same mistakes.

Unfortunately, I was always working on intranet webapps so I don't have much to show/port except what I've already mentioned. Maybe one old (angular1) application for making invoices.

@egasimus
Copy link

egasimus commented Apr 3, 2020

I think there being no audio API is a feature rather than a shortcoming. In my opinion, it's crucial to confine the scope to just the GUI engine, rather than reimplement the whole browser. As a potential Graffiti app developer, I'd benefit from having to bring my own audio code - or better yet, delegate all that to a daemon via some form of IPC. A diversity of implementations is better than a diversity of hacky workarounds atop a default implementation.

On the flip side, I think first-class support for hot module reloading is quite important - the more instant feedback when building a GUI, the better! I've seen HMR being done even in C++ with JUCE. I've done a few experiments with hot module reloading in Node; the most self-contained one so far is dothot, which does not attempt to do dependency tracking at all; it relies on calling require() within the bodies of functions instead of at the top of the module. This has the intention of shepherding people into a more functional style. I think I also have some similar code somewhere that implements dependency tracking as well.

For me, the important takeway here is that most HMR implementations target a frontend loaded over the network in a browser, and optimize for that use case (Webpack has "web" in its name, heh). This makes them leaky abstractions. I'd much rather see just the delivery method abstracted away, so that if I'm building a Graffiti app which is local-first, and only incidentally accessible remotely via browser, I would have an iteration speed of e.g. 100ms vs of 1s (90% of which due to traversing the network stack to localhost, tree-shaking, minification, all of which are irrelevant in that case). Yes, hardly anyone would say something about 100ms vs 1s feedback loop when coding a GUI, but I think it still makes a difference.

I totally get you about always working on intranet webapps, I'm the same :-) Luckily I also have a big stash of unfinished side projects which I'll be more than happy to dust off once I've found a way around #152. Maybe once I have picked up some speed with Graffiti I could even record some live coding videos, been on my mind for a while.

One last thing, have you seen Arcan? I see it as having some common ground with Graffiti, in terms of "indie project that attempts to get rid of all the accumulated cruft in the GUI stack". It has a bit more of a "kitchen sink" approach and "Unix greybeard" mentality I guess - which I totally admire, but I'm more comfortable with Rust, Node and the DOM as opposed to C, Lua and imperative drawing, which is one reason I find Graffiti so relevant.

@cztomsik
Copy link
Owner Author

cztomsik commented Apr 3, 2020

I think there being no audio API ...

Agreed.

On the flip side, I think first-class support for hot module reloading ...

Yes, something very simple is already there - you can see it in hackable-tv
I've been trying different modules/approaches but it always had some issues here and there. It's probably not easy to make it work with all of the different transpilers and their plugins/configurations. It is definitely something I want to fix but I'm also thinking about providing some cli bin so you could gft run --watch myfile.js and it would simply forget everything except global object (and window) and node_modules and it would run the file again (no module.hot, no need to override require or anything like that, if you want to keep something, just put it to global). That way I think it might be possible to support React Fast Refresh too.

I'd much rather see just the delivery method abstracted away, so that if I'm building a Graffiti app which is local-first, and only incidentally accessible remotely via browser, I would have an iteration speed of e.g. 100ms vs of 1s (90% of which due to traversing the network stack to

100% agree, that's why that naive hmr.ts is there and why I was trying different modules (https://github.com/sidorares/hot-module-replacement worked the best but not so good with typescript and export * from ... and import { ... } from '.'). There are many gotchas.

But feel free to try it with your dothot (I'm not sure I was trying it)

Luckily I also have a big stash of unfinished side projects

This is great!

One last thing, have you seen Arcan? I see it as having some common ground with Graffiti, in terms of "indie project that attempts to get rid of all the accumulated cruft in the GUI stack". It has a bit more of a "kitchen sink" approach and "Unix greybeard" mentality I guess - which I totally admire, but I'm more comfortable with Rust, Node and the DOM as opposed to C, Lua and imperative drawing, which is one reason I find Graffiti so relevant.

Never heard about it but I'll have a look, thanks :)

@nanfang2000
Copy link

I would like to run the React based GUI app on a cheap embedded device without the heavy of electron or chrome/webkit.
my target device: 64MB storage and 64MB RAM on a 600Mhz ARM9
is that possible? Looking forward to your project to be light replacement of electron

@cztomsik
Copy link
Owner Author

64M storage should be fine but RAM might be tight depending on how big the screen is (framebuffer can take a lot) and how much mem pressure your js script is going to make. You will also need GPU with OpenGL 2.1 or GLES2 (at least for now)

I got it running (~59-60fps) on raspi zero w but that's 512M. There's also $5 version without bluetooth if you need real lowcost. Stay tuned, new version is around the corner (with support for CSS-in-JS frameworks)

@nanfang2000
Copy link

Thank you @cztomsik ! I have a Allwinner ARM A7 SBC that has 128MB DDR, with GLES2, which I believe is easier to fit. Waiting forward to your project, well done!

@jelemux
Copy link

jelemux commented Jun 27, 2020

I'd like to build webapps that also run on desktop with Rust compiled to WASM and maybe vue.js client-side and preferably something like Rocket server-side. Would this be possible with graffiti?

One idea for a project that I have in mind would be an creator/editor for application letters and curriculum vitae that then generates and outputs a PDF with different styles and layouts.

@cztomsik
Copy link
Owner Author

cztomsik commented Jun 28, 2020

Graffiti will always be just a subset of DOM/CSS so you'd need to only use what's supported but otherwise it should work. Currently, it's limited to inline styles only but it will eventually (life is sometimes hard & unexpected) support most of the CSS (probably excluding sibling selectors and some pseudo elements).

PDF would be possible but it's currently out-of-scope (everything is rendered directly to OpenGL)

If you need PDF, electron is still the best choice.

@egasimus
Copy link

egasimus commented Jul 24, 2020

@cztomsik What subset of HTML5 DOM API support is to be expected? Is there a foundational design document of some sort that determines the scope you are currently aiming to achieve?

Can I embed a video? Render SVG? Do I have Canvas? I know that at least some of those browser features are implemented in pure JS in Node-land so that could become part of the core Graffiti as the Rust equivalents mature (and someone does the assumedly non-negligible integration work?)

Can someone bolt a HTTP lib on to Graffiti, write a URL bar in HTML5 and make a browser? It runs WebRender under the hood, right - so can I just write in <MyComponent> tags that have no default behavior and define everything with JS (I'm presuming whatever engine you're embedding can handle anything sane I throw at it, I presume) and CSS (again, what subset, and what defines the subset, if it's based on WebRender?)

Never got beyond some hello world examples in a crazy Nix environment. But figured out that Nix the package manager (which you can get on any distro) has this crazy double #! trick where you can use Graffitti to write a GUI app in a single. fucking. file. (if it fits ofc, I'm emphasizing the lightness of boilerplate as compared to any GUI project even a Web/Electron app nowadays)

@cztomsik
Copy link
Owner Author

Never got beyond some hello world examples in a crazy Nix environment.

Wow, that looks really great!

What subset of HTML5 DOM API support is to be expected? Is there a foundational design document of some sort that determines the scope you are currently aiming to achieve?

no feature matrix for now, sorry... it's a moving target but the scope is:

  • enough of DOM to run react/vue/svelte/xxx and most of their popular libraries
    • no shadow DOM, deprecated APIs, by-the-spec validations/error-reporting and obscure things like document.write()
  • most of the CSS except sibling selectors, inherit, pseudo-elements, media-queries
    • no CSS transitions for now (but you can use react-spring and similar libs)
    • layout limited by what stretch or yoga can/will do

Can I embed a video? Render SVG? Do I have Canvas? I know that at least some of those browser features are implemented in pure JS in Node-land so that could become part of the core Graffiti as the Rust equivalents mature (and someone does the assumedly non-negligible integration work?)

I'd like to do that eventually but it's rather going to be separate plugin

Can someone bolt a HTTP lib on to Graffiti, write a URL bar in HTML5 and make a browser? It runs WebRender under the hood, right - so can I just write in <MyComponent> tags that have no default behavior and define everything with JS (I'm presuming whatever engine you're embedding can handle anything sane I throw at it, I presume) and CSS (again, what subset, and what defines the subset, if it's based on WebRender?)

  • there is no embedded "web" engine here, everything is done from scratch
  • webrender unfortunately is just multi-threaded 2D rasterizer (not a web engine) and I'm not using it anymore because it doesn't support raspi
  • to make browser you'd need to implement a lot of things yourself and security would be a huge problem (one reason why browsers are slow & mem hungry is that they do a lot of tab-isolation & sanitizing)
  • in theory you could monkey-patch document.createElement() to create your own element

@JoCat
Copy link
Contributor

JoCat commented Apr 14, 2021

Hello, I saw a mention in the GUI thread for Deno, I decided to take a look. I would like to create a lightweight client for the Minecraft game with simple customization using a web technology stack. I'm currently focused on Electron, but looking for better alternatives. At the moment I am using Vue. And in principle it would be nice to have access to basic stuff. 😅

@cztomsik
Copy link
Owner Author

This is from-scratch HTML/CSS engine so no canvas (yet), but there's WebView (macos-only for now) so you could do that. You might also have a look at tauri - but that's a bit different approach. Graffiti is just nodejs/deno module so it's one import and you have it. Eventually I want canvas but I need to work too so no promises :)

@JoCat
Copy link
Contributor

JoCat commented Apr 14, 2021

ouch, I didn't put it right, I'm writing a launcher that launches the client in a separate process, in my case canvas is not required, at least for now))

@cztomsik
Copy link
Owner Author

oh, ok then that might be good fit for graffiti, you essentially just need to create index.html and one main.js file where you create window (like with electron) but it's still broken at least until weekend, sorry.

the previous version should work fine but api was different and now we have much better support for standards - it's already passing fraction of WPT

@JoCat
Copy link
Contributor

JoCat commented Apr 14, 2021

Yes, I tried to run graffiti, but I ran into the same error as here #157
Well, I'm in no hurry anyway, so there is time)

@cztomsik cztomsik pinned this issue Jun 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants