The issue is that this isn't actually an Electron alternative; the author is upfront about this not actually being a browser-compatible rendering engine. It's just a rendering engine that happens to use some subset / superset of HTML, JS and CSS, but it is not compatible with web libraries and components.
As a basic example, SciterJS crashes loading the "hello world" ReactJS project (at least it did last time I tried it - the author recommended I used a custom version of React he publishes). It's perfectly fine to come up with a lightweight cross-platform UI rendering engine (we know we need more of those), but having it web-adjancent while not really web-compatible is a recipe for frustration.
- Element.patch(...JSX expression...) - native VDOM reconciliation implementation.
- Element.append/prepend(...JSX expression...) - DOM population by JSX
- Native support of lifecycle "events": componentDidMount/WillUnmount and componentUpdate.
So after reading the post it seems you switched to a new language for your framework, integrated a new language runtime and implemented all these additional features for that runtime within half a year? And you did that all by yourself? That's pretty incredible.
I really like these and think it'd be great if browsers implemented them.
People upthread are complaining that you can't take some common web libraries and use them in Sciter, but have you given any thought / effort to the opposite? Having a library/polyfill/source translator that allows you to use sciter code in the browser?
These are all great things, but the fact we can't take some well-tested, used-by-millions library from npm and start building on it makes things very confusing.
It also makes skills non-transferable for the millions of web developers out there. Imagine hiring a SQL expert for your project that uses SQOL which is almost SQL but not quite, so everything they learn won't be useful in their future SQL jobs and the quirks / differences will make them pull their hair out and call it quits in short time.
It almost feels like building an entirely new language would be a better choice (maybe TSX+CSS, with no HTML) to reduce frustration if nothing else.
I appreciate the work you're doing on this project, as always.
SQL is a particularly poor choice for your analogy, as there are no two dialects of SQL that are exactly alike, both in basic syntax and much more importantly in performance characteristics. And yet, knowledge of SQL is mostly transferrable between Oracle and Postgres, between MSSQL and SQLite and so on.
Basic skills are very much transferable between e.g. Ruby and Python, despite a ton of differences.
More narrowly, skills are transferable between ReactJS and React Native, despite a ton of component and CSS differences. Skills are transferable between Java-based and Kotlin-based Android development.
So I'd say that a well-defined subset of web APIs, without strategically placed footguns, could be a quite okay target; if code is not directly reusable, it can be easily ported.
That doesn't sound like an "issue", that sounds like a perk. Even the "crashing running ReactJS" part. If my semi truck crashes when I tilt it over on 2 wheels like a motorcycle, I don't call it an "issue".
I don't know. I like small and minimal, synonymous with Fabrice Bellard (TCC and QuickJS!), and I am glad the herd of elephants wasn't dragged in the door! But then again, I am not a front end dev or a full-time coder; I have been coding since 1978, and I don't only reminisce about small OS's and programs, but I think there should be an alternate path on software dev focusing on minimalism. I program in APL/J for starters, and C and Lisp (April at the moment, a subset of APL in Lisp), so I am happy to play with JS using QuickJS. I tried React, but it just exposed my non-front-end eyes to just how layered and large these ecosystems have become. I guess when that's what you work with all day, it's so familiar you take it for granted. I'd love to hear thoughts on this due to my ignorance on the matter. Thanks!
> having it web-adjancent while not really web-compatible is a recipe for frustration
Exactly. What's the point of using HTML/CSS/JS for a desktop UI, when you can't make use of the incredible amount of effort that has been spent on frameworks, toolkits, and libraries to make building a HTML UI bearable?
I don’t know exactly what’s supported by this thing, but it’s certainly not a strange idea to choose a subset of functionality to support that covers a huge range of use cases but improves performance, predictability, maintainability, file sizes, etc. Strict mode in JavaScript is a similar concept.
I see, in this thread, talks about what Sciter does and does not offer.
It's not the only alternative to Electron, but it might be one that offers predictable and repeatable results.
I released a small open source project on HN last week (https://github.com/Fusion/pngsource) and I wrote its backend logic in Go. I built the frontend using Tailwind (https://tailwindcss.com) and DaisyUI (https://daisyui.com) and, using Go compiler flags, I can release the app using both WebView (github.com/webview/webview) (which, yes, does require the host OS' collaboration) and Wails (wails.app) (which also does.)
On Linux/AMD64, the binary's size is 3.7M when building for WebView, and 6.8M when targeting Wails.
The way the app works is I drag/drop files to the UI, magic happens, and I use github.com/ncruces/zenity to prompt the user for a save location.
It's been working pretty well on Linux, Windows, MacOS. I think WebView's approach of limiting the feature set is working well as it feels more "native" than Wails (better refreshes and resize operations for instance)
However, I already have a few tickets reporting that, for instance, the app is displayed as a blank window in some environments. And it's hard to debug remotely, obviously. So, this is where Sciter may be a better option.
it's not embeddable and not portable, therefor doesn't qualify as a proper GUI toolkit, at best it is a plugin toolkit for windows's integrated web browser
When I look at all the "Kinda interesting" projects on my hard drive that died out halfway-through, and compare myself to Fabrice, I think that Fabrice is merely:
- One of the least lazy people ever
- Mentally healthy
- Not publishing small projects he does for himself
- Able to consistently pick projects that are both useful and clearly-scoped.
The project-picking trick is, make programs that work on existing data.
When I make a game, 100 hours of work does not yield even 1 hour of good gameplay, and the game doesn't do anything but let you play the game.
But when Fabrice makes QEMU, there is already a bunch of OS images you can try out in it. When he makes ffmpeg, there is already a bunch of media files to decode and transcode with it. When he makes JSLinux, there is already Linux stuff to play with. And QuickJS runs existing JavaScript code.
Being too original sinks a project. Every time you see a fun project like "I made my own virtual machine, OS, and language," remember, that project is a game, which provided 100 hours of fun for the developer and maybe 1 hour for you. The game is self-contained and doesn't gain any value by inter-operating with the rest of reality, because the VM, OS, and lang are all one-offs.
Fabrice isn't held back by the idealism of "I'll rewrite the world all at once". His stuff is great because he's replacing individual components with stuff that works better, in the same machine. Like GNU did.
This is in a nutshell what great software design is all about. Always asking the question, what is the least amount of work I have to do to achieve the most results?
Refactoring tons of code gets you used to seeing these patterns, but he is operating at a much higher level of abstraction.
He is clearly an incredible smart guy, but I had the same thought. He work projects that most of us would never start, and that elevates him even higher.
The interesting part, me being dumber, how much of could I accomplice assuming the same level of dicipline and similar routines?
Since there is presumably no commercial advantage to keeping TIScript proprietary, it would be nice to open source it. It was a shame when Opera announced that they were moving to Chromium but didn't throw the Presto sources over the wall at the same time. I think we have to treat it like that code is never going to see the light of day, which is unfortunate, since even under restrictive copyright regimes, eventually books and movies become public domain.
DO:
- Use LGPL or GPL for TIScript, if you want; customers who need something further away from copyleft on the spectrum of open source can continue paying
DON'T:
- Equate open sourcing the code with running an open source project and all the overhead that comes along with it and then decide not to do it for that reason; throw it over the wall with a license slapped on it and don't ignore the "NO WARRANTY" section (this is the thing that 99% of GitHub projects with burned out maintainers get wrong)
- Get bashful about code quality and say "I need to polish it up first"; nobody cares (since Sciter has already been shared source for a while, I don't expect this to be a problem, but just trying to cover all the bases here)
> It was a shame when Opera announced that they were moving to Chromium but didn't throw the Presto sources over the wall at the same time. I think we have to treat it like that code is never going to see the light of day...
The Presto source was leaked years ago. You can't use it for anything you're going to release, of course -- but it's out there.
I'd really like to see Sciter take off to mainstream. If I was asked to do an application with specific custom designed UI, I'd use Sciter.
I have given it a go some months ago, alongside with Delphi and it's really really easy to get started.
It's not open source yet, but... hey! it doesn't have to be to be to be successful.
Of course, Terra Informatica doesn't have the same level of marketing budget than Microsoft/GitHub to promote it as Electron, but a project can rise to relevance by its own merits I believe. I usually err on the side of naïvety for these cases.
sciter is pretty successful already - https://sciter.com/ lists a number of recognisable commercial users and estimates 340 million installs over its lifetime. i very much doubt it will go mainstream without being open sourced though; closed source is simply a mindshare killer for this kind of developer-focused project.
Functional superset but unfortunately not a strict superset. I regret a bit that I did not follow ECMA spec closely with initial TIScript (I am an author of Sciter).
It was damned too easy to fix those birth defects of JS so I could not resist to do that right from the beginning ...
I’m concerned that you’re falling into the same trap here with integrating your own variant of JSX, and mulling over adding more things like hyphens in unquoted object literal keys.
JSX is popular enough that it’s safe, ECMAScript isn’t going to break it, but your alterations to JSX are already significantly incompatible: you have <input.search /> being equivalent to JSX("input", {"class": "search"}, null), but the JSX everyone else is using has that equivalent to JSX(input.search, {}, null). I’m not certain if your JSX syntax is supposed to be able to be used with React code or anything else that uses JSX syntax, but if yes then it’ll be broken in a significant number of cases so that it’s worse than useless, and if no, well, it’s going to be misleading, and what if JSX did get merged into ECMAScript in some form? Then you’d be incompatible with ECMAScript again.
Same deal with hyphens in unquoted object literal keys: it’s not part of ECMAScript now, but just because it’d be a syntax error now doesn’t mean it always will be. Decorators in TypeScript are a good example of things going badly wrong even when an extremely popular project is involved.
I say: if you want to go JavaScript, go JavaScript, maaaaaybe plus standard JSX conforming with <https://facebook.github.io/jsx/>, and no further. Even if what you do is obviously superior, &c. &c. I’d apply the same reasoning on your fork of CSS: you introduced it for a good reason back then, but now it’s just friction, even if it’s a little better in a vacuum (and maybe it is in parts, maybe it isn’t in other parts).
This <input.search /> is a short form of <input class="search" />. You can use either one of those. And `JSX(input.search, {}, null)` does not make sense. But `JSX(Input.search, {}, null)` does make sense, yes. In Sciter that will be `JSX(Input-Search, {}, null)` to use Search component from Input module.
You are not obligated to use built-in JSX. TS compiler includes its own version of JSX compiler and so it will not hit built-in implementation.
"Same deal with hyphens in unquoted object literal keys: it’s not part of ECMAScript now"
This was used in TIScript but not in JS, unfortunately.
The semantics of the JSX transformation certainly do vary, though there’s a fairly consistent baseline which you’ve broadly matched; yet for all the variations in semantics, the JSX syntax itself is well-defined, and that’s what you’re flouting. In fact, since we’re talking of semantics, one of the ways in which the runtime (post-transformation) semantics vary is a good indication of the problem of special-casing your own syntax: your class syntax transforms into a property named class, but React uses className for the equivalent concept.
JSX(input.search, {}, null) makes perfect sense as code and as a concept, though that particular combination of names would be surprising. But suppose it’s something like props.tagName, or library.SomeComponent. As for your JSX(Input-Search, {}, null) being module lookup… I hope that wouldn’t be valid code, and that <Input-Search/> transforms into something other than that, or you’ve got grave problems. But again, this is a point where you’ve deviated from standard JSX syntax in a way that’s far too likely to cause trouble down the road. Why not rather use Module:Component or module.Component, both of which are syntactically valid JSX? (I dunno if these modules are global or have to be imported or whatever, so I don’t know what’s most appropriate.)
Concerning hyphens in keys: I’m referring to what you’re suggesting as a possible addition to your brand of JavaScript. I’m suggesting that it would be better if you resisted the temptation to alter JavaScript at all, beyond possibly standard JSX syntax.
For what it’s worth, JSX is exactly designed for this kind of usage. It’s just a syntax extension, and it only specifies the way syntax can be used in an expression position. It explicitly allows dot access (but doesn’t specify its behavior).
While it’s common to treat JSX as syntax sugar for hyperscript, even that isn’t specified. JSX is a compiler hint with expression semantics, that’s all. You can see how dramatically different it can be in plain JS by looking at compiled output from dom-expressions (most commonly used in SolidJS).
It was generally presented as an extension of fairly ancient JavaScript, but as a non-user I believe it was only ever like JavaScript, and not a superset even at the start, because of things like splitting numbers into integer and float types. And since then, the two had diverged, quite significantly and incompatibly in places (in semantics, I mean, not just syntax).
So weird - I just found this out naturally when visiting the Sciter homepage last week and I didn't recall it ever being said that this would ever be done. I do remember the author's brief moment where he was considering open-sourcing it with QuickJS as the engine.
On the Rust side, I've been looking at Tauri, but would much prefer it be usable with something other than the host webview, like Sciter. Tauri offers a bit more of a complete API for desktop apps and it would be nice to have my cake and eat it too.
I keep wondering how feasible it would be to have something like Tauri ship with a simplified webview, so it could still be consistent across platforms but still without the bloat of Electron. Although really, the problem isn't using the host's view so much as IE's webview being the default on Windows.
Even better, a lot of the necessary complexity involved in getting the web stack to look and act like native could be done away with by redesigning a version of that stack optimized for displaying applications rather than documents.
It would no longer be the web stack but it could take the advantages of it without the shortcomings.
where would the simplified webview come from though? that is precisely the value sciter delivers - a roughly web-compatible view that is much lighter weight than a full-fledged browser engine.
Just a bit of empathy, I can relate to your loss, c-smile. No matter how good your idea is, the crude force of “web standards best practices top frameworks wow salary” inertia can crush every noble endeavor and almost nobody will even notice it’s status quo, not the only way.
I'm interested in exploring the state of memory management in between pure ownership trees and all-out GC, including stack-allocated structs, refcounting, cycle collection, and per-thread-enabled GCs. I found https://bellard.org/quickjs/quickjs.html and https://news.ycombinator.com/item?id=20413561 when looking for more information on QuickJS's cycle removal, which mentions the "Bacon cycle collector".
Ref-counting GC and in particular implementation that is used in QuickJS is more deterministic I would say.
In QuickJS:
function Foo() {
let file = new File(...);
file.write("Happy New Year");
}
The file variable (object in it) will be destroyed immediately at the exit from the function.
Which is more suitable in case of Sciter that is embeddable [in native applications] engine.
Contrary my TIScript that I was using before had real moving/compacting GC. Objects were freed at GC cycles (in galaxy far far away from invocation).
Now try an data structure, with an unknown size of elements that can non-deterministically scale to several hundreds nodes and delete the graph root node.
Which is why all high performance Ref-counting GC rely on background threads for when RC reaches zero, thus mimicking tracing GC implementations.
Is this substantially worse than deleting a vector<unique_ptr> holding a few hundred nodes (which I don't really notice, but might be bad without me realizing)? Either way you're doing a traversal and running hundreds of destructors and deallocations, but in the refcount you need an extra deallocation and compare per node (which should be cheap compared to deallocation, if non-atomic?).
Related tangent: Is anyone aware of any CSS frameworks that are "native-like" and not generic web-based things?
E.g. if I want OS-style UI components + styles like a browser tab-strip or pane splitters or toolbars etc?
There are loads of things out there with UI elements, but they seem to be focused on webpage use-cases and design patterns, and so are not really suitable for desktop apps running in sciter/electron/tauri/neutralino/wails/others
Reading thru the spec for the language brought back PTSD flashbacks from doing InDesign scripting with ExtendScript https://extendscript.docsforadobe.dev/
I have a little progressive Web app I'm currently rewriting in Vue 3. Was hoping to toss it in electron for cross platform desktop use. Now I think I'll give this a go first. Great work!
Electron is large because it is a pack that combines full fledged web browser (WebKit) and server (NodeJS).
Web browser engine is designed with these priorities:
1. to provide safe browsing experience;
2. to present web pages in standard manner;
Note the order. Safe browsing means the following:
1. You must run user facing UI (tab) in separate process. This involves RPC with the rest of application.
2. You cannot allow any executable code other than managed JS. And so you MUST provide JIT or something like that as JS is the only option to run anything.
The order requires and leads to a lot of code to support those priorities.
And why would you doubt that? You used to be able to run a whole Linux distribution from a floppy.
It's not a complete alternative, so a lot of APIs and features that Chromium has are missing. The Chromium dev team isn't focused on size, but speed and features. While an alternative that does less can focus on size.
It is actually not the fact that V8 in context of Sciter alike use cases will be faster.
Consider this statement:
document.body.patch(<body>Hello world</body>);
In case of Sciter this expression runs with native speed. JSX is built-in and element.patch() method is native.
While in browser, in case of ReactJS, you will run that patch() (reconciliation procedure ReactDOM.render) with JS VM speed as that algorithm is implemented on JS/TS.
My guess is probably the QuickJS has less resource usage compared to the more performant V8.
UPDATE:
Now I have read the linked article, here is the reasons (copied from the article):
API and integration principles are close to what TIScript uses – it took me just 1 month to add QuickJS to Sciter core. And 4 months more to expose HTML/CSS runtime to JS.
Relatively compact implementation – QuickJS is slightly more fatty (by 100 kb) but still in acceptable range. For the note: full version of V8 is about 40 mb – 5 times larger than Sciter itself;
Liberal MIT license. Sciter cannot use GPL/LGPL code – many customers expressed this requirement;
There is a section with the key reasons it was picked, in particular:
"Relatively compact implementation – QuickJS is slightly more fatty (by 100 kb) but still in acceptable range. For the note: full version of V8 is about 40 mb – 5 times larger than Sciter itself"
40mb is just nuts. These days, jlink would allow me to shrink a Java JVM down to something like that. And that would already include some nontrivial batteries, which Javascript doesn't AFAIK.
Pure V8 - yes, close to 8 Mb - that is still larger than whole Sciter that beside of script VM contains HTML/CSS/Graphics, etc.
40 Mb came from Node.JS distribution (V8 + native runtime = node.exe).
Sciter is more comparable to NodeJS as it includes good chunk of NodeJS alike runtime too.
While I appreciate the conscious size-saving effort, I need to ask: is 30 MB difference that big of a deal for desktop applications nowadays? A random Electron app that I download will easily take up hundreds of MBs disk space.
I personally don’t think it’s acceptable and the disregard for files sizes generally extends to disregard for RAM usage which is even more unacceptable. Sadly I don’t really have a choice regarding using most of these apps.
Is it even possible to distill V8 into a single Windows DLL anymore? The version I use was about 3.5 MB in 2013. I tried updating it a couple of years ago, but quickly gave up and backed away, groping for the doorknob.
It's possible though not straight-forward. React Native Windows seems to have a version of V8 wrapped with JSI (for use in React Native) though by the looks of the project, it appears to be only used internally and not really meant for stand-along consumption: https://github.com/microsoft/v8-jsi
I wonder what are the global scale environmental consequences will be, long term. Could it make a difference between couple nuclear reactors urgently needed and no longer needed?
“golden 40 seconds” rule: for the user, to buy a product, it should not take more than 40 seconds from the click on “download” button to the UI to appear on screen.
The issue is that this isn't actually an Electron alternative; the author is upfront about this not actually being a browser-compatible rendering engine. It's just a rendering engine that happens to use some subset / superset of HTML, JS and CSS, but it is not compatible with web libraries and components.
As a basic example, SciterJS crashes loading the "hello world" ReactJS project (at least it did last time I tried it - the author recommended I used a custom version of React he publishes). It's perfectly fine to come up with a lightweight cross-platform UI rendering engine (we know we need more of those), but having it web-adjancent while not really web-compatible is a recipe for frustration.