React Native for Windows and Mac
microsoft.github.io
microsoft.github.io
http://npm.anvaka.com/#/view/2d/react-native
From my experience, it's really great to work with and definitely saves a ton of work, but the depgraph above fills me with doubt for use in sensitive applications such as in finance or healthcare. For this reason, I've been trying out Flutter or even considering to go back to native apps. Perhaps there's some kind of middle ground where we can create a tight microkernel-like thing natively using secure enclaves and key managers, but expose an API to the "untrusted" parts of the program. This approach is not without its own downsides, such as dark patterns in a compromised UI. However, as one friend pointed out, a lot of those deps are indeed for build time only, which have different risk profiles.
The depgraph of reactjs is far simpler and easier for me to understand and therefore feel trust:
http://npm.anvaka.com/#/view/2d/react
Does anyone know if there has been reliable research towards the security of the entire RN dependency tree? Seeing a stray dep there that has 1 maintainer on npm/GitHub who has been inactive for over a year makes me nervous. Any one of those JavaScript projects could do something nefarious deep under the hood, and this to me seems to expose a huge surface area for attackers.
Here's a classic throwback to keep us on our toes :)
But as I browse it, most of the dependencies seem to be build-time, not runtime dependencies (i.e. it seems like most of them are related to Babel). The React comparison doesn't include dev dependencies.
While react-native does have more dependencies than vanilla react, on first glance the list doesn't seem too crazy https://github.com/facebook/react-native/blob/master/package...
Plus I forgot to address this in my earlier comment: that visualizer only shows dependencies. By default it doesn't load any dev dependencies. You can confirm that for yourself by checking out https://npm.anvaka.com/#/view/2d/rollup for example - only the single runtime dependency on fsevents shows up, the dozens of dev dependencies Rollup has don't.
So yes, React Native does ship that overcomplicated graph of dependencies to all its users. I'll grant that at least _some_ of the code in those dependencies gets tree-shaken out.
The line between dependencies and devDependencies got blurry the second npm packages got used for more than just Node.js itself. What's really needed to remove the ambiguity is something like prodDependencies, which would be a subset of the current dependencies, but I don't know if it's really worth it.
EDIT: To be clear - maybe I am REALLY old-school, but every time we did a release, we archived our tool-chain (GCC blah blah, Make blah blah, bash blah blah), our depencies, our vendor libraries and our code, so that IF in 20 years, if we had to rebuild a particular release (12.x) for a particular client (Chase) on a particular platform (AIX), we could do so de novo. Maybe that was overkill, but in a world where everything changes, why wouldn't you snapshot everything for every release?
Maybe I'm old - but I don't trust Quickbooks-in-the-Cloud.
EDIT: But I use 'em!
If not, this should be trivial to replicate today using docker containers.
The thing that made it work, though, was the fire-drills. Once a quarter (at the beginning, later it was once a year), we would go buy about 10 servers from dell and set them up in the common-room and say to the employees. "We just got hit by a meteor last night. Get us up from off-sites, including all company documentation. Re-inflate the company in 4 hours. Start Now". Of course we all failed (sometimes the backups didn't even work!), but we got to the point where we could re-inflate the company in four hours. I was so proud of those people.
A fine grained capability system for packages would dramatically improve the safety profile, and if this were built into package.json and the lockfile we could do the following:
1. Packages advertise what their default capabilities should be limited to 2. Changes in those capabilities are encoded in the package lock file, and can't be changed without the user explicitly affirming them
¹ and other langs with extensive use of package managers and micro-packages
I think Deno does that (the new project by Node's original creator):
Maybe it's a start of better tooling? Kicking out a graph of package/permission call stack might be useful to audit
Maybe it could be solved by type checking during dependency resolution time: instead of just checking version numbers, also check capabilities that transitive dependencies declare.
Maybe you could slowly boil the ocean by assuming that everything that doesn't declare required capabilities implicitly requires the "ALL" capability, and triage+prioritize a growing core of packages that have explicit capability requirements. In my mind it's kind of like purifying functions in a library: you start at the lowest level / leaves of the call graph and make sure they don't do any I/O, and then the things that call them can be made pure and so on up the chain.
That sounds like it would be working. If you declare that your package doesn't need network, and it fails because it used the network, that sounds like a bug was caught.
But npm-snark aside, maybe some lack of trust must come from a highly modular open source ecosystem.
If a library I ship could abstain from unneeded platform capabilities, that would certainly reduce catastrophic bug/attack surface, and I'd sleep better.
With tighter snyk integration into npm and the acquisition of npm through ms one could argue that security bar may have risen/will rise but I (speaking as a js/ts dev) am still sceptical. I haven't really looked to deep into stuff like selinux/apparmor/firejail [3] maybe someone can give an opinion on this. I'd wish for something that would be codeified on package level to make review easier and give me some peace of mind.
For now my plan is to dockerize most of my projects and it's dependencies. It should give a little more protection against malicious postinstall scripts.
Unfortunately, I depend more and more on npm modules outside of projects (coc-vim comes to mind/for others it may be vscode etc.).
[1] https://medium.com/hackernoon/npm-package-permissions-an-ide... (2018) [2] https://medium.com/hackernoon/im-harvesting-credit-card-numb... (2018) [3] https://github.com/netblue30/firejail/blob/master/README.md
It would be a huge quality-of-life improvement for React developers, not to mention the improved security and reliability.
Or not. I've worked on plenty of applications that had few if any dependencies for those things. I'm sure many others have too.
In some cases that was because we didn't need that particular functionality. Routing has little value if you're building an in-house SPA that always starts from the same dashboard anyway, for example.
In other cases, it's because we're programmers and don't import entire library ecosystems to do what we could do ourselves with a few lines of code or some APIs that are already supported by all modern browsers anyway.
I liked React when it first arrived, because it was a tool that was that did one useful job and did it reasonably well. I dislike the direction it's taken more recently, because it now seems to be trying to do several jobs and not doing most of them very well at all. I understand that this is partly because of the way some developers coerced React into doing things it wasn't really suitable for and the React dev team have been responding to that, but I still think value has been lost in that process.
It really doesn't bode well for microservices of any large scale complexity, unless there are concentrated meganodes with limited interconnects like cities and superhighways.
Bloat though ... I mean, if every npm module was simply a directory with a package.json file and a couple js files I'd be happy. But thats almost never true, and usually for bad reasons. I'm not sure how to fix the problem. A few years ago I worked with a guy who maintained a popular little 200 line react image component on npm. The project website was great - with example images and whatnot. Some software we worked on used his library. Our node_modules was huge, and one day I took a look to try and figure out why. It turned out his tiny module was bundling all ~10mb of example images in the package itself.
He was shocked and embarrassed when I pointed it out to him. The library had thousands of stars on github at the time. Lots of people were using it but nobody had noticed and mentioned it to him.
10mb isn't that big, but this is the sort of sloppiness that really adds up over time & thousands of transitive dependancies. Would tooling fix the problem? Maybe a little, but I suspect the problem its partially cultural. A lot of the web development community suffers from a lack of ... thoroughness. Like, the expectation is if the website works and looks pretty, you've done a good job. And invisible bugs and issues get overlooked consistently. Like app bundles which silently include multiple copies of the (200k) moment timezone database. Or obvious security issues that web devs just don't know to look for. I suppose this is how juniors learn - but it feels like a very lonely place sometimes when you have skills and experience.
Meanwhile WinAmp was sooooo tiny.
If you want to know what it's like to have everything break LITERALLY every few days, use react native.
Its annoying, but I succeeded in upgrading in one project in about 1 hour. Just basically comparing the example code diff on github.
perhaps older version had more changes and weren't documented as well.
irrelevant comment: I hate Expo as it fails to be a helpful abstraction on top RN.
The update wasn't terrible.
I understand the rationale for going async -- you can never be sure exactly how long anything will take, and invisible things like memory management and caching can blow up your runtime; and if you get synchronous operations wrong, that leads to spinning beach ball cursors and “app not responding” errors, which are even worse than lag. But in that scenario, an async app isn’t going to perform any more usefully, you’ll just get a blank or frozen screen instead of a beach ball.
That might still be better (I'm undecided, personally), but it's worth recognizing that heavy native app is still there, just shared with a lot of other JS apps.
This also voids the argument "we need Electron, because it reduces development costs, and we can get truly cross-platform apps". Ripcord is written by a single indie developer and runs on Windows, Mac, and Linux. Imagine what could be done if Slack employed a team with 10 Qt developers.
Most web apps are egregious. The problem is that there is a whole generation that is not exposed to Delphi or Qt Designer and have the false believe that developing web apps is an order of magnitude easier. It's only an order or magnitude easier for them, because web tech is the only thing they know. Heck, I was writing GUI apps as a 12y/o with Delphi.
They will definitely notice. E.g. baseline MacBooks (which is probably what most people outside developers buy) still come with 8GB RAM. If you subtract the OS, video memory, and some disk caching. There is not that much left on modern macOS (or Windows).
Having Slack + Skype in the background and some tabs open with modern web sites/applications can easily much a few GBs of RAM, slowing down quite a lot of 8GB machines. I guess most developers just don't notice, because their employer give them development machines with 16 or 32GB RAM.
People don’t care.
They don't care because they don't understand. They will just believe that their computers are slow and that they have to throw more money at it. Or they just buy an iPad and it will feel fast, because Apple does not allow every application to ship and run its own web browser.
no offence to the dev of ripcord; IMO qt and gtk stuff always just looks super outdated
That's because the developer decided to use their own theme. I have made a few Qt apps and on macOS and Windows you can barely distinguish them from a native app, unless you know where to look. Fully agree with Gtk+ though, it does not follow platform styling and conventions and is very slow on macOS (don't know about Windows).
This says so much about the sad state of modern software development...
When native development is a last resort.
As an end user why do I care about "openness"? If I pay a premium for my platform, why would I want second rate cross platform software?
Falsehoods HNers believe about how people buy/use software. Didn't stop Slack/Discord from become ubiquitous.
"But native tho" just becomes a circlejerk. Talking about what users care about, most people don't know what native means nor if a given app is it. They don't know if Zoom is using more memory or CPU than it "should".
How many people know that Slack is battery draining monstrosity?
The only people that pay for Slack are companies. The definition of Enterprise Software is where the user is not the customer.
In the famous words of Jobs about Dropbox -- chat isn't a product, it's a feature.
Other than VSCode for Rust and TypeScript, my own personal computer is as much Electron free as possible.
So don't mistake market share for freedom of choice.
The important thing is features - which VSCode has, and the speed at which those features are developed and deployed on all platforms - where VSCode is nearly peerless.
If developers cared about performance and resource consumption above all else, no one would be using VSCode right now (you included). They’d be using vim, emacs or perhaps Sublime. But that isn’t the case.
So why does HN keep flogging the “electron is bad” meme?
Also, I wonder how much the Electron love overlapps with VSCode, after all many of those developers were pushing for Atom before VSCode was born.
I think Microsoft chose Chromium for Edge mostly because they have big plans for Electron.
I'm just saying users don't care. They'll still use software that has the features they're looking for, on the platforms they use, as long as performance is acceptable.
I'm pushing back against the idea that performance nuts on HN who won't install a single electron app are somehow representative of the population at large.
Edit: a word missing
Indeed, even Java and .NET are improving their AOT stories, while available since the early days, weren't as widely deployed as they could have been.
Are you paying for your software or getting whatever you can find for free? If you are paying, is the software's leanness something you value - that is, will you buy some software because it is leaner over some other software that is heavier? Would that be even if the heavier software has more features?
What sort of software have you bought? I'm asking seriously, not trolling - i've bought Total Commander myself exactly because it was lean (check: windows calculator vs one of the most feature packed file managers[0]) but i do not think there are many that value things like that.
On mobile, I’ll pay to remove ads and I won’t use any software or games where I can’t remove ads.
With the economy in the crapper, I’m starting to voluntarily pay more to support my favorite content producers.
Office is not written using one of the cross platform frameworks and is usually only around 3-9 months behind when it comes to taking advantage of new features as Apple releases them.
Plex is server software. The UI is a web page.
R# itself is a plug-in only for Visual Studio for Windows. Yes Rider is cross platform, but I don’t have a need for it.
The only other software I mentioned are games. No one expects a native experience from games.
this is something that you might value but I think it's fair to say it is already a minority position.
phones and the web have become the primary platform for software delivery, and people do not treat their desktop if they even have one as some sort of premium platform, it's a terminal for the internet.
at this point, people are probably more familiar with the look and feel of web applications than they are with native applications and value similarity across platforms over features of individual platforms. The operating system and the hardware are increasingly becoming irrelevant and a detail compared to the web on top.
Who values desktop software enough to pay for it? I know in the Mac market at least, the few indy developers making money are not writing apps using cross platform SDKs.
Plenty of money to be made desktop solutions to life sciences, manufacturing, factory automation, aren't plugging their air gaped dashboards to the web.
Anyone doing music composition, graphics, animation, infotainment systems.
In Europe there are enough Win32, WPF, UWP, Qt related jobs and consulting projects with hourly rates to do a comfortable living.
As for B2C, it is always going to be an uphill battle regardless of the application type, there are only so many application types that one is willing to pay for outside established brands, and SaaS is a much better way to avoid piracy and get everyone to pay.
But either way, you kind of made my point. Consumers aren't paying for applications built on cross platform frameworks outside of games.
In most countries they just need to go the local market or get hold of one of those lists distributed among students.
All those small companies that manage to have their software exposed on shops like Saturn here in Germany, or do direct sales over their web site.
And just because it is B2C, Prosummer or used via a tablet plugged into a docking station, it doesn't stop being desktop software, from the points of view who's paying and selling it.
And regarding games, anyone with experience on the field knows how much harder it is to make any kind of living out of them versus regular desktop software.
The success/failure rate is much higher, with the large majority of studios never making any dime.
And if you look at the end consumer software which have billions of users, who in one way or the other pay for it, it's almost always built on web tech these days. Discord, Skype, Slack, Spotify, and so on.
Of course there's professional or industrial software written in native code. But that's not because it's popular, it's because it's niche and specialised. The business model of charging upfront isn't exactly a sign of popularity, if anything it's the opposite.
No one cares about the Spotify UI. People don’t interact with Spotify that much. They listen to it.
The business model of charging upfront isn't exactly a sign of popularity, if anything it's the opposite.
In a capitalist system how else do you measure value than what people are willing to pay enough for to have a sustainable business? End users aren’t paying for Slack. They are using the free plan because it’s good enough.
Are you just going to find a different reason why you're going to ignore software built on a web tech-stack? Add up the market valuation of all companies using web technology to bring software to their users. Then compare it to the native market. It's not even close.
It's perfectly fine to use market value to estimate utility in a capitalist system. You just can't ignore every piece of software you don't like.
Why would you think React Native would be less bloated than native apps?
What are some well done cross platform apps that don't unnecessarily drain battery life? I can think of one - VSCode.
You're talking about Electron there, which like phonegap is a browser wrapper and a different thing to RN. I don't believe RN is known to be a battery drain in general.
React Native for Windows and Mac specifically, none. We commenting on an article about its launch. It's a bit early to be talking about that.
Cross-platform frameworks like Electron or Flutter, loads. VSCode, Skype, Discord, WhatsApp Desktop all use it. Of course you might argue that they're all selling services rather than software but that the point really is that the companies authoring those apps want to keep costs down, give users the same experience everywhere, and believe cross-platform apps can give users a good experience.
More developers, more applications of software.
At the same time, performance has a tangential relationship with computer code being interpreted or compiled to native.
After all, Java is compiled to byte code and powers plenty of high traffic servers efficiently.
Many AAA games use ActionScript, Python, Lua, etc for their UIs and scripting for mods.
While it's true that there is no substitute for code compiled to native when high performance is called for, I think it's justified for native development to be last resort.
This is coming from someone who codes primarily in C++, where high performance is important. I wish I didn't have to.
How well has Java done on the client in the last two decades?
Many AAA games use ActionScript, Python, Lua, etc for their UIs and scripting for mods.
What's the actual performance sensitive parts written in?
So I am not sure what you are saying. Everyone that is able to is compiling their stuff to try to regain some efficiency.
The reason is that people wants to do more complex things with their software nowadays, and hardware can't keep up with the trend. There is also battery life, smartphones, tablets...
Those are the reasons we are seeing a resurgence of native development.
This isn’t just me being a Mac snob. I found Apple’s few Windows apps over the years to be just as bad.
Yes and a long time ago Sun came out with Swing. How did that work out?
Even before that MS came out with P-Code and the abomination that was Word 6 for the Mac.
I think it clearly shows that complex UI apps require cross platform UI, or will remain single platform (Xcode, Visual Studio).
I was at a crossroads in 2008. I had been developing mostly in C for a decade and decided to pivot to being your standard “Enterprise Dev”. I had a choice between moving my career to C# or Java. I chose C# partly because of the bad stench of the cross platform Java IDEs at the time. Give me VS or Xcode any day over a Java based IDE.
Photoshop definitely isn’t using a non native runtime. I doubt that Blender is either.
But for writing C# apps in a Windows computer, the old VS was already miles ahead back in 2010. It is a really good product. It had RAD tools, testing, deployment, source control, database migrations, all wrapped in a very snappy and convenient GUI that I still don't think VS Code replaces properly. As much as I love the command line and unix philosophy, there was something about such a complete IDE that made me very productive. All IMO of course.
However I strongly believe that VS Code will get better and better with time and be able to fully replace old VS even for this use case in the future.
My favourite is the factorio research tree. It gives you a sense of depth and you can select dependencies.
Maybe I'll implement it one day when I have the time.
Imagine how much more enjoyable npm would've been if prominent JS devs took a sane approach to dependencies, like the TypeScript team who have no runtime deps.
The resulting npm deps of hell [1] means they need to rely on complex build solutions like Webpack to manage it all. My preference these days is to avoid npm/yarn all together and just use TypeScript watch (tsc -w) for incremental updates which lets you develop modern JS using modern fx's (e.g. Vue/React) without any of the npm/Webpack complexity & only requires a vastly simpler build solution to minify/bundle all UMD deps together.
[1] https://www.reddit.com/r/ProgrammerHumor/comments/6s0wov/hea...
I'm actually surprised, I thought React had many more dependencies.
Edit: Removed comment related to typo, no longer relevant.
The core library deps isn't relevant, it's how many deps the smallest starting Create React App has that matters [1]. As mentioned by OP react-native is far worse.
Also, with TypeScript, Babel becomes completely unnecessary. I haven't used it in any of my React projects for years. Many templates still include it by default to match the JS version, but if you create the project from scratch without any scaffolding, there is no reason to do so.
You can see all the dependencies it installs by running:
$ npx create-react-app my-app
> Also, with TypeScript, Babel becomes completely unnecessary.Right, as per my comment it's also my preferred approach:
> My preference these days is to avoid npm/yarn all together and just use TypeScript watch
In general I prefer Vue over React, but I prefer to use vanilla TypeScript & UMD deps to develop with either.
> Many templates still include it by default to match the JS version
It's what the React team is recommending to start with [1]:
> Create React App is a comfortable environment for learning React, and is the best way to start building a new single-page application in React.
[1] https://reactjs.org/docs/create-a-new-react-app.html#create-...
However, the resulting `package.json` only shows 3 dependencies: react, react-dom and react-scripts. After `yarn build`, it added 3 more things from `@testing-library` (https://testing-library.com/), I assume those things won't make it into the production bundle.
react and react-dom only depend on a tiny number of things, you can check that with any dependency visualizer. 6 or 7 in total for the whole tree, and most of those are tiny things that they just split off from react itself (e.g. prop-types).
react-scripts is the huge beast that causes the dependency tree to explode. It is a `create-react-app`-specific package that contains all its build logic. So that seems to confirm the hypothesis that there actually aren't many runtime dependencies in the basic template, but who knows what it does behind the scenes. Also the LICENSE.txt file it generated for the biggest output .js file only includes entries for react, react-dom and object-assign.
No idea about React Native.
> No idea about React Native.
The OP suggests it's worse. But I no longer use React Native as I kept running into bugs & UI issues that were never fixed. I ended up reporting a few with complete repro's but didn't look like they were ever looked at, instead after a few months they decided to triage their 1000s of open issues, to get back to zero issue inbox.
IMO React Native is architecturally flawed to run into so many issues when creating normal Apps after years of development, maybe if there were more developer resources on the team it would be more manageable. But I believe Flutter has a much better architecture [1] which feels much more integrated & polished that results in a more responsive app that works as advertised.
For mobile right now, the easiest, most headache-free solution may actually be to forget about cross-platform and just do separate Android and iOS native apps. You won't need to do things like hunt for a bunch of 3rd party libraries whenever you need to use Bluetooth or something.
Once SwiftUI and Jetpack Compose mature, that process should be much more pleasant as well.
It definitely isn't, Dart is an advanced clean, strongly typed classical language without JS's warts that's just as clean & productive with a clean complete & well-defined standard library, native support for modules, consistent async/await in all libraries, etc.
I love TypeScript, but it's major productivity advantage over Dart is in JS's dynamism, something that's a lot more restrictive in Dart because it needs to support AOT, which is what allows it to compile to native code & advanced linking + tree-shaking, resulting in its better performance. So there are areas where you need to use code-gen, but having wasted an eternity trying to diagnose runtime issues in C#/Xamarin in libraries that use reflection, I'd much rather use an AOT language that only provides language features that natively supports AOT then running into frequent on-device issues that only occur at runtime.
> For mobile right now, the easiest, most headache-free solution may actually be to forget about cross-platform and just do separate Android and iOS native apps.
Nope, Flutter's Reactive UI & live-reload is far more productive then developing using native iOS or Java/Kotlin tools (which can also be used in Android Studio). SwiftUI is close if you just need to develop for iOS, but I find Dart/Flutter to be a lot more productive than using Swift & Xcode's woefully poor tooling support.
It also doesn't seem to have things like sum types, which would be pretty easy to do in an AOT language. The expresiveness, the ability to accurately describe data structures with its type system just doesn't seem to be there. It seems about on par with Java in that regard. Fast live reload is pretty good though, I hope other langauges/frameworks put more effort into that.
I haven't used it much beyond simple demos though.
TypeScript is even worse in that regard since it has to deal with JS that wasn't written in TypeScript & there's no way to verify the runtime object complies with the interface you say it does. Then of course JS has to deal with multiple null & undefined values & even more falsy values, ultimately TypeScript provides nice static analysis but also a false sense of security as there's no guarantee that the compile time static analysis matches the actual types / values at runtime.
At least with Dart, you're guaranteed everything is written in Dart so you can have confidence in the static type analysis is actually going to be valid at runtime. With that said you can use the `--enable-experiment=non-nullable` to enable its Sound non-nullable Types feature [1]
> The expresiveness, the ability to accurately describe data structures with its type system just doesn't seem to be there. It seems about on par with Java in that regard.
This is a gross mischaracterization that I'm just going to assume you're familiar with Dart at all. It's vastly more modern and less verbose than Java in basically all aspects: type declarations, auto properties/getters/setters, auto constructors, implicit interfaces, factory constructors, mixins, typedefs, inference, lambdas, async/await, extension methods, optional parameters, string interpolation, single integer type, cascade/chaining, null guards/assignment/coalescing, generators, operator overloading, Callable classes, first class functions, everything's an object, duck typing with noSuchMethod, etc.
More often this can happen with external data (typing incoming JSON responses), but you have to run-time validate those anyway.
`null` is only rarely used in JS, `undefined` is by far the more common one, and of course the types reflect which one is a possible value, so it's not like you can miss it by accident.
Falsy values are only a problem with bad practices - inside `if`, I just always use the full form with the `===` operator, e.g. `if (variable !== undefined)` instead of `if (variable)`. A lint rule can be enabled for that. There is now also the `??` operator which prevents the common misuse of `||`, e.g. `const a = variable ?? 'default'`.
So those things aren't really issues in practice.
You are correct in assuming that I'm not very familiar with Dart, I have only used it very briefly. I have only checked whether specific features such as sum types were available.
That's not true, `undefined` is not even a keyword or type, `null` is what you would use if you wanted to specify a variable has "no value" in JS or JSON (again because `undefined` isn't a Type). The "undefined" value is only for specifying if the variable "does not exist". The difference is important as the behavior is different depending on how you use them.
> I just always use the full form with the `===` operator, e.g. `if (variable !== undefined)` instead of `if (variable)`
This is bad practice as you're only testing for `undefined` here, not `null`, this is basically the only time where strict equality isn't useful. You want to test with `if (variable != null)` which tests for both `null` and `undefined` and not other falsy values that `if (variable)` tests for.
> There is now also the `??` operator
Right, the Nullish coalescing operator (which Dart/C# also has) tests for both `null` and `undefined` (well `void 0` since the `undefined` value can be overridden) and not falsy values.
So if I have a type `User|undefined`, testing `if (user === undefined || user === null)` is pointless, as `null` is not part of that type. It would be different if it were. Similarly, it makes no sense to test a variable of `User` type for value `false`, like it would if the type were `User|boolean`, or even `User|false` which you can do in TypeScript (not that you should). So `if (variable)` is still bad (ok for booleans, tolerable for some types but better avoided). You only test for what the variable can contain.
Some types you encounter are `T|null` - mostly DOM things (e.g. the return value of getElementById), but some JSON stuff as well like you said. Even though a lot of JSON just has optional properties instead, which for all intents and purposes work like `|undefined` when reading them.
From my experience, it is much more common to deal with `undefined` in the JS ecosystem, whether that is by omitting properties from objects, or explicitly assigning/returning `undefined` somewhere.
`T|null|undefined` types are ever rarer. Only for those it makes sense to test for both null and undefined.
By the way you can also have types like
type RemoteData<T> = {ready: false} | {ready: true, data: T}
in TypeScript, which is better than { ready: boolean, data?: T }
because you don't have to worry about "does `data` still make sense when it is non-ready?", the type clearly tells you that it doesn't (of course you can also have a different type where it would, the point is to accurately describe the structures you deal with). Then, if you do a check if (remote.ready) {
console.log(remote.data.length)
}
it knows that data exists inside that `if` block, so you can safely access it without `!` or `?`. Similarly, inside `if (!remote.ready) { }`, you cannot access it at all. It also won't let you pass an object with { ready: true }, but no data of the required type to `RemoteData<T>`.It's very relevant, your TypeScript definition is meaningless at runtime when it's executed JS where all TypeScript's type information is erased, the only checks are relevant are the runtime JS type checks.
> `if (user === undefined || user === null)` is pointless
Right, it is verbose & unecessary, so is only testing for `if (user === undefined)` which is inadequate and I don't know anyone who'd use it since using the recommended `if (user == null)` is shorter and more complete for testing if any value is not `null` or `undefined`. If you're validating JSON you should know that there is no `undefined` type in JSON, but any value could be `null`.
> From my experience, it is much more common to deal with `undefined` in the JS ecosystem, whether that is by omitting properties from objects, or explicitly assigning/returning `undefined` somewhere.
If a type want's to declare that property exists but doesn't have a value it would be `null`, which is also the only option you have in JSON to do so.
Your TypeScript definitions are for your code structure and API description so you can benefit from its static analysis, but you should be aware they do nothing at runtime where all Type annotations are erased so if you try to define your Vue component with an optional property, e.g:
class MyComponent extends Vue
{
p1?:string;
p2 = null;
}
It gets stripped away completely but setting a null value instead will ensure the property exists and is made reactive: var MyComponent = /** @class */ (function (_super) {
__extends(MyComponent, _super);
function MyComponent() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.p2 = null;
return _this;
}
return MyComponent;
}
It's important to know what guarantees TypeScript does for you, what effects the type annotations have and what their behavior is at runtime.But there are only a few ways in which that can happen:
- a bug in type definitions - a JS library with .d.ts files which "lie" about the actual types - this is no different than any other bug in a library, needs to be reported and fixed. In my experience, such bugs are not very common (I've yet to encounter one).
- non-validated external data (JSON coming from HTTP) - like I said, you have to validate external data (or assume that anything can be anything). You kinda have to do it in all languages, though ones with reflection and a deserializing library can do that somewhat automatically and throw a runtime error if the deserialization fails (although that is not full validation).
- incorrect explicit casts and using `any` - e.g. `const a: number = ('asdf' as any)`, but less stupid and more accidental. This is a bug in the casting code, similar to doing an incorrect `reinterpret_cast` in C++. There is usually little reason to do explicit casts in TypeScript code, outside of very small isolated pieces of code.
Which means you generally don't have to worry about any of this. Relying on those guarantees is good enough for 99+% of situations (I mean, some people even use dynamically typed languages and survive without doing tons of checks on every other line of code).
---
Testing stuff which is not expected (by the specified type) to be `null` for `null` is just as pointless as testing it for the number 10. There is just no "valid" way for the `null` to have gotten there (just like the number 10). It would be extremely paranoid and only add noise to the code.
If there is a valid way, then the type needs to be `T|null` (and then you need to test it), not `T`, otherwise it's a bug. For TypeScript code, this will be checked automatically, for JS library type definitions, it needs to be made correct manually.
Regarding JSON and undefined, you can omit properties in JSON. E.g. sometimes have {"user": {"name": "Bob", "email": "bob@example.com"}}, and sometimes just {"user": {"name": "Bob"}} without the email. Such an optional "email" can of course be expressed in TypeScript, and can be tested as `=== undefined`, which will return true if it's not there. And such a pattern of omitting properties from objects (not just JSON) is much more common in JS than assigning `null` to stuff.
You are much more likely to find a JS object where some property is sometimes there and sometimes not there but never `null`, than an object where it is always there but sometimes `null`. That's what I mean when I say `undefined` is much more common than `null` in the JS world. But neither is a problem, you just need to have types which correctly describe what values the properties can contain.
---
So typically none of this is a problem in practice, as long as you have correct type definitions for the JS libraries which you use (i.e. there is no bug in them, just like there should be no bugs in the library itself) and don't do funky casts with `any`.
Unlike most languages, TypeScript is just a high-level static analysis compiler service that compiles to JS that executes in a JS VM. It has no control over what happens at runtime, it doesn't know about external libraries and user input, how its TypeScript functions are going to be invoked. All it can know is the "truths" you tell it to assume, of which it makes no attempt to validate whether any of your assertions are accurate. It's not that TypeScript is wrong as it can only verify the compile-time state of your program, it doesn't know or can control the runtime state of the JS VM, what arguments your functions are invoked with, what values properties are set with, how any of its instances or prototype chain is manipulated, etc.
> Testing stuff which is not expected (by the specified type) to be `null` for `null` is just as pointless as testing it for the number 10. There is just no "valid" way for the `null` to have gotten there (just like the number 10). It would be extremely paranoid.
It's strange to read runtime JS type checks is pointless when it's the only way you can validate for sure what a Type is. You seem to think you can resolve issues by declaring typescript annotations in a different way, when they have absolutely no impact, your type annotations does not provide any guarantees at runtime, TypeScript can't tell you if your Type annotation is accurate now or will remain accurate in the future, if what you cast to is accurate, if how your code is invoked is accurate, you're telling TypeScript what the only types for a variable are, but these type assertions have no impact at runtime. Ask yourself if you're only checking for `undefined` what the behavior of your program is when it's called with `null`. Since JS functions have positional arguments it's very common for it to be invoked with `null` argument values when needing to provide values for each argument, whereas it's almost never explicitly called with an `undefined` value unless it's undergoing regression testing for bugs.
Given any JS variable can be assigned both `undefined` and `null`, there's no good reason for using strict equality check for `=== undefined`, it's always the wrong type check unless you need to determine the difference between `null` and `undefined`, otherwise it's just a more verbose inadequate type check for nothingness.
In practice, say I have
type User = { name: string, email: string }
let loggedInUser: User = { name: 'Bob', email: 'bob@examaple.com' }
or even // Can't change the contents, only reassign the whole variable
let loggedInUser: Readonly<User> = ...
and only ever use that `loggedInUser` from TypeScript code (because my entire codebase is TypeScript), and I avoid the 3 scenarios mentioned above (buggy JS library type definitions, non-validated external data, casting/any/`!`).How would a `null` email ever get inside `loggedInUser`? It just won't happen. I know there are no run-time checks - I don't need any run-time checks. I don't need 100% theoretical guarantees. I can be reasonably certain that `loggedInUser.email` will always be a non-null non-undefined string. It's a good enough™ practical guarantee. A null-check on `loggedInUser.email` would be pure confusing noise (because anyone reading it would go "wait, this can be null? I thought it was non-null").
Do you have a practical explanation of how a `loggedInUser.email === null` situation might occur given the above assumptions?
>Given any JS variable can be assigned both `undefined` and `null`
Any JS variable can be assigned literally anything. I don't need to check that `loggedInUser.email` is not null, just like I don't need to check that `loggedInUser.email` is not a boolean or a number. Because how would that even happen? Not having to do those checks is half the point of having a static type system in the first place (the other half is being notified of type errors at compile/edit time).
If you need to defensively check whether something so basic that is never supposed to happen has happened, then the code is already a giant unmaintainable mess.
E.g. `const a = [1, 2, 3]` will let you do `a[5]` and still give it type `number` instead of `number|undefined` as mentioned in the github issue. Many other languages also do this (though they have runtime checks/errors).
So that kinda sucks, but the rest still stands (there is still no practically realistic way for `null` or anything other than `undefined` to get there). Hopefully they'll fix that in the future with a new compiler setting.
Fortunately, in such industries you don't have to worry about being cross platform particularly. Go write C# and WinForms (or whatever it is these days). Or use Lazarus/FreePascal if you do need to be cross platform.
https://hacks.mozilla.org/2019/11/announcing-the-bytecode-al...
https://www.npmjs.com/package/number-is-nan
Want Array#filter/map/reduce? Why that'll be three separate packages:
https://www.npmjs.com/package/array-filter https://www.npmjs.com/package/array-map https://www.npmjs.com/package/array-reduce
It just seems to be the culture of the Node.js crowd to take a library, break it up into functions, and publish every. single. one. as a separate package.
To criticize this organization, you would need to understand why people find that to be valuable and show a better approach.
You’re attributing it to “culture” but there may be deeper, less arbitrary reasons. Look up “ponyfill” if you are interested in learning about it.
I’d rather trust a fairly big library with an organized open source group behind it than thousands of small libraries by unknown developers.
A week!
Of course they don’t hold a candle to “is-number” which has 29M/week
Of course this is completely unrepresentative of reality because “yolo just install dependencies at deployment” may mean it’s downloaded 5 or 10 or 50 times for a high traffic site/service with a bunch of backend installations.
Also the legal team likes this a lot more too. If a data leak occurs due to some library that Microsoft wrote, we have one company to sue. If it's a react package, who the hell do we go after? Most of these are "at will" / MIT license style things, so we are more or less SOL anyways, but legal teams don't like hearing that.
You also get at a more fundamental question. What is trust? Why can we trust a larger organization over a collection of individuals? Are they not the same thing? What social structures make one more trustworthy over another?
There's a great book on this by Bruce Schneier called Liars and Outliers. I highly recommend you read it.
Polyfills and single-function libraries are just two different problems with the NPM ecosystem.
isNaN() has been in the language forever. And in case you really need Number.isNaN() (because it's weird for isNaN('foo') to be true), it's been there for quite a long time too. Not enough to be on IE, sadly, but certainly more than enough to be on the modern JS engines React Native runs on.
So, at least for React Native, the package number-is-nan shouldn't be necessary at all. But it's probably a transitive dependency, and that's basically the problem with all these sort of polyfill packages: you might not need them, but a library that runs on older engines on which you depend (directly or transitively) does need them, so you end up paying the price anyway.
which actually if I look at number-is-nan it returns
return typeof value === 'number' && value !== value;
I never use the typeof value === 'number' myself because I always know if what I'm checking is NaN should be a number of not, but probably that's a bad habit to get into.
KPIs are always the driver. Also for programmers.
I wonder if React Native can do all of this officially, but I suppose that's not their prerogative, given that RN is mostly used by Facebook for apps and these other platform efforts are by third parties, like Microsoft here.
"Native" doesn't describe the programming language, but the GUI layer. Native == non-web-browser.
You can choose one of two things:
1) Run a single precomputed action or animation in native-land when receiving an event from JS. No interaction is possible.
2) Run a requestAnimationFrame loop in JS which is passing the bridge (6 API calls on Android - 3 layers per direction) 60-120 times per second in async mode. Enjoy the jank.
What dependencies are you using that continuously broke? Did you track your package lock file on Git?
EDIT: Ive also tried React Native Web and it pretty much worked OOTB. Alerts were the only thing I found that weren't implemented, but they didn't show any runtime errors or instability
Except hot reload
Expo is wonderful for prototyping and quick iteration. The ability to use Snacks online and see them working on the phone is great.
But beyond that everything in RN feels hacky and unfinished. While working with it I had some silly issues with Metro, and found some subtle bugs in Text and Button components.
About the "Native" part. I think that a lot of people have the expectation that doing RN apps will be the same as building a iOS or Android native app. But RN+Expo is not that different from frameworks like Ionic. Is really hard to do an app that follows the Apple HIG or Material Guidelines, you end with something in the middle that doesn't look or feels truly native (at least not without tons of extra work to imitate things that you get for free in the native UI kit) .
RN without Expo is not so nice, lots of rough edges and sooner or later you'll need to write interop code in Objective-C or Android Java to take advantage of the native platform.
If this happens over a weekend, expect your phone to blow up every three hours until it gets republished and fixed.
It’s nothing like ionic. When is the last time you used RN? RN apps are hard to tell from native.
The RN's core Button it’s a Text composed with a Touchable (https://github.com/facebook/react-native/blob/master/Librari...). It behaves in the same way but there are subtle differences in text rendering: the font size and letter spacing is not exactly the same, so when you create a native looking iOS view it doesn’t look the same unless to fine tune the font settings (and of course that will break when iOS decides to change it). This is just one small example, another one in iOS is “routing”. With the RN Router you don’t get the native components but a simulation of it. But Apple HIG doesn’t document many details of the animations and behavior of headings and nav bar (they assume that you use the native component). So if you want to have a native look and feel your options are: try an alternative router built for iOS, try to build your own adapter (hard unless you have tons of native dev experience), or try to imitate the native platform. All the options have pros and cons, and require more extra work over a small UI detail that you get for free using native tools. At least Flutter took the effort to make it look native by default.
In the end is similar to the desktop: if you want cross platform code is easier to not follow the platform rules. The differentiator of RN is that you have the option to embed the native widgets, which is not always easy. (The last time I used RN was mid-2019, I didn’t see substantial changes since then)
As of RN 0.60 it has been completely smooth sailing developing a react native app sans expo IMO
I'm quite sure and aware of people that love it, but just from my personal development background, it just never really seemed appealing to me. Definitely not a fan of how state is handled. I've rolled my own system, Redux, and a host of other solutions as well. It just all seemed unnecessarily complex.
As you said, to me it just felt like hacks on top of hacks. I'll take vanilla iOS and Android development any day of the week, and twice on Sunday.
With that said, and from what I've seen of Dart/Flutter, I really hope it takes off.
I'm sure every React developer has at some point found themselves banging their head on the wall trying to figure out why some child component isn't updating.
And yes, it's a personal preference, but I'm also not a fan of Javascript. If another client wants a single codebase app, I'm really gonna give Flutter a nice long look. I've read the docs, and it looks quite appealing.
Did you know that Redux is now basically built into React?
https://medium.com/simply/state-management-with-react-hooks-...
https://blog.logrocket.com/use-hooks-and-context-not-react-a...
https://www.simplethread.com/cant-replace-redux-with-hooks/ https://daveceddia.com/context-api-vs-redux/ https://medium.com/javascript-scene/do-react-hooks-replace-r...
TL;DR Context can replace some but not all of Redux. Redux can figure out which components to rerender based on what's being computed. Context doesn't, so it's basically the same as refreshing your entire component tree every time something changes. You could build it yourself, but at that point, you're just reinventing Redux.
I also like the Redux Toolkit (https://redux-toolkit.js.org/) which is an opinionated way to write Redux that cuts down the boilerplate a lot. createSlice is easily one of the best features, you can encapsulate Redux logic for each different type of content, like authentication, users, posts, etc.
I'm currently working on updating the Redux core docs to teach RTK as the default way to use Redux. Hoping to have the new "Quick Start" tutorial page up in the near future.
For Redux with React, you could check out Redux Toolkit (https://redux-toolkit.js.org/). It solves a lot of the boilerplate issues with Redux. createSlice is especially valuable.
I guess the first is not backed by a big company and the second still has the Cordova stigma.
I also couldn't find ways to easily implement things I want, e.g. native Mac MenuBar bindings/Mac App Store payment library etc.
Eventually I ended up using Quasar https://quasar.dev/, which allows you to use one Vue.js codebase but deploy to Cordova on mobile and Electron on desktop. Vue is definitely not the prettiest solution out there, but I had to be practical and actually get the app out.
Maybe I'm just one year too early for React Native/Flutter ecosystem to be developed enough for my app. The landscape is certainly changing rapidly, which is good.
Regarding Windows and Linux, I too was surprised at how well everything worked. You can't build to production yet for these two platforms (officially at least, see flutter-rs for unofficial implementations), but the debug builds still work as well as the Android and iOS emulators. I used them on a lower powered machine to run my Flutter apps and it was great that they worked well.
I prefer solutions like Xamarin / Mono where you can have a Cocoa UI coupled with C# or F# based dll's. Let's be honest, as long as you have a good way of maintaining a good state in your app for example by already using ViewModels that did most of the heavy lifting like formatting strings, having the state in a state machine and so on, getting the UI to work as required is just an exercise of filling in the colors between the lines.
Barely anyone would notice they were using a Xamarin based solution on a Mac, while the JS based applications are immediately really obvious to the trained eye.
Splice is now on flutter, including web. I'd say that is a pretty demanding app.
I watched their talk video [1] and they seemed to have only built an MVPish app using Flutter (ie, less than a year using it + a team of two devs). And it only seems to be for the desktop app?
Maybe I'm missing where they are using it on the web... but I wouldn't call this a huge buy in.
GP asked for evidence of Google abandoning things, and Angular.js is exactly that.
Upgrading to an incompatible framework is not supporting the old one.
Every major revision of software has breaking changes (or as you call them, "incompatibilities"), some more than others (see Python 2 -> 3).
That doesn't mean it's "abandoned". Google made major API changes and renamed it to better communicate that it's not some simple JS framework – calling that abandoned is disingenuous. It's only abandoned in-so-far as every old version of every software ever gets abandoned at some point.
I cannot upgrade.
I have to port, due to the backwards-incompatible changes.
Those changes may well be for the better, but for those of us maintaining stable programs, porting means increasing risk of failure for no perceivable end user benefit.
Microsoft is much better at supporting old tools and software, at least historically.
Not exactly abandoned - it seems to have been maintained for 10 years, although no stable release for the last couple of years.
It does feel like it would have been a dead end to get into though.
My worry with Flutter is the same - it won't get large enough adoption by other tech companies, and Google will move on to something else.
I think it'll still hang out as open source project. But will it get the large investment to make improvements as the various OSs change over the long time?
It's mostly the browser's ecosystem moved away from these for more standard based approaches.
FWIW, I think your criticism is broadly valid, in that it's more of an exception for Microsoft, but much more common for Google. It's not hard to look at the Windows dev ecosystem, and see which parts of it are very stable, and likely to be around long term - because they have already been around for very long indeed.
Silverlight in other hand is a technology no modern web browsers support (in the same camp with gradually deprecated Flash and everything that requires plugins.), and perhaps to Microsoft it's a lot less justifiable to update it beyond security update.
[0] https://softwareengineering.stackexchange.com/questions/1555...
I am curious about how often this sentiment gets brought up about Go or Kubernetes.
flutter on the other hand is tremendously complex, and has yet to display any major company having bet their future on it.
There may come a time when this applies to Go.
Postgres is not new. It was part of my stack 10 years ago. So many new people have moved to postgres it has become hot.
You lose all advantages that HTML and CSS gives you, links, styling, accessibility, text selection! ... It's basically a flash website... Which admittedly is okay for some applications
Flutter for Web is still on Beta, so lets see where it lands. Today, it seems to implement some PWA practices and lazyloading to try and get some performance.
Checkout the official [1] Flutter web demos. Even the simplest [2] example renders basically every part of the UI (including text!!) within canvas elements, which is a bit crazy to me... but yes it's still Beta, so we'll see what they can improve
Admittedly I need to go back and check but it was confusing and worrisome.
How did you query this? I want to have a look, but the fact "flutter" shows data since 2004 means the terms I'm using are inflated [1]. Flutter is a dictionary word after all.
[1]: https://trends.google.com/trends/explore?date=all&geo=US&q=r...
https://trends.google.com/trends/explore?date=all&q=react%20...
The biggest gripe I have with React-Native is the many JS packages on npm that we can't use due to how the code is exported. It's a huge hack job, which Flutter absolutely destroyed by having everything I needed as a package that just worked.
One thing I'm looking at on Flutter, is how their public packages age. If I can't use a 3 year old package on modern day Flutter, there will be some big problems coming soon.
That said, there's an effort in the community to find maintainers for older packages that people find useful. If you come across something that you need, post back, or shoot me an email.
I seriously hope that Flutter fades. It's very dangerous in many ways. Even ignoring the huge downsides of basically having a new Flash, consider this: the massive Flutter layer is, surprise surprise, yet another Google project that is magically _significantly_ slower in Firefox. I don't mean a small difference here, I mean that on a brand new fancy flagship I tested on, Flutter in Chrome is buttery smooth and Flutter in Firefox is a miserable, laggy experience. If it gets popular, this will become yet another reason pushing people off Firefox and cementing Google's dominance of the web.
Flutter is a very, very dangerous thing.
My personal hope is that Flutter gains traction and the web can move beyond current web/native technology. Postscript / PDFs aren't suitable for game experiences...and to my mind web standards have been shoehorned into supporting web apps, where there is a mismatch with native technologies. I'd like to think that Flutter can help bridge that gap.
This is not to say that accessibility etc. should be ignored...nor better support in Firefox...but even Brendan Eich is using Blink/V8 with Brave.
Anyhow, thoughts of one.
I loved what Flex brought to the table. Too bad Adobe didn’t open source flash and let it die.
Having worked with/on React Native for ~3 years I am definitely not a fan but at least React Native enables using native components directly even if this happens too rarely.
- consistent rendering/support across multiple platforms and versions
- multiple windows
- rendering to a window that isn't owned by the UI being rendered or created by the framework
Can I do that all in React native? Edit: don't need to bring up electron.
Or you can build native WASM apps?
There seems to be some preview on the mobile native, though, it's probably not strictly a WASM as it provides binding through Xamarin...[0]
[0]: https://devblogs.microsoft.com/aspnet/mobile-blazor-bindings...
It's a hairier problem than you'd expect it to be. I'm not an expert but my understanding is that it's tricky to deal with the event loops when you're not the master of your domain, at least in a platform agnostic way. The workaround is usually to spawn multiple processes, but then the management of app state has to have an IPC layer underneath the internal APIs and there needs to be a master daemon running somewhere.
In keeping with front page posts, the plugin API for Apple's Logic Pro (audio units) is an example of that. You are handed an NSView* and need to render on it, but you don't create it.
Legit question, I just started using Electron, hadn't heard of the former and thought the latter was a selling point because all platforms wrapped Electron's Chrome.
Rendering consistency is generally pretty good; I haven't run into any issues with that.
EDIT: Ok I see now, you listed your requirements and just stated that Electron doesn't satisfy them. The construct is confusing to me because the way it's worded seems to suggest Electron doesn't satisfy any of them, but I understand now.
If electron is Chrome and Edge is Chrome and Microsoft uses Edge for this - then its all chrome in all directions. Native is much faster and more powerful - WE MUST RESIST!
Here's the GitHub for the Windows implementation: https://github.com/microsoft/react-native-windows
And here's the fork of React Native for the Mac one (it doesn't seem to be as polished as the Windows one yet): https://github.com/microsoft/react-native-macos
It uses flex-box (and only flex-box) for layout, adds some convenient shorthands - marginVertical, marginHorizontal, and does some surprising (but useful) things like has transform take a JS array of key value pairs - https://reactnative.dev/docs/transforms#transform
React scripts native widgets, not HTML.
- multiple platforms...
Yes: Windows (x32,x64, ARM64), from XP to 10, MacOS, Linux/GTK, IoT and mobiles.
- multiple windows -
Yes. Multiple desktop windows and you can even render separate DOM elements in popup windows.
- rendering to a window that isn't owned by the UI being rendered
Yes, you can render it on top DirectX, OpenGL, Vulkan (coming) or in child window/nsview/gtkwidget. There is also Sciter.Lite that allows to render UI without any DWM - on frame buffer / video memory directly. Check : https://sciter.com/sciter-and-directx/
- don't need to bring up electron.
Not Electron. All this in monolithic dll/so (5..9mb) that even can be linked in statically.
- consistent rendering across multiple platforms.
Check screenshots of https://notes.sciter.com/ , are they consistent enough?
- ... for React
React (Reactor in Sciter terms) is implemented natively. JSX (SSX in Sciter) is a part of language/runtime - no need for additional compilers, etc.
- I'd love to abandon my C/C++ ...
No need to. You can still manage (update, handle events) UI directly from C++ if needed. You can even create custom native DOM elements that can even draw themselves by native code.
I can't really commit to sciter and your flavor of JS until it has a larger community, more docs, and more onboarding materials so I can get teams up to speed and working quickly, reinventing fewer wheels, and have more discoverability in your docs and community so I can even know how to do things and what I don't need to rewrite.
Some bencharks comparing engine performance to V8 would also be much appreciated.
2. "larger ecosystems..." Sciter is embeddable and extendable engine, this means that you can extend it by existing native libraries, time proven and effective. Here is how SQLite native namespace looks in Sciter: https://github.com/c-smile/sciter-sdk/blob/master/sqlite/sci...
3. "it has a larger community..."
I am aiming not to larger but rather more professional community. Sciter sources contains patches from these dev teams: https://sciter.com/#customers Security audit was made by Symantec and 3 more AntiVirus vendors. All that... Source code base is compact enough for a C++ programmer to get into when needed.
"Some bencharks comparing engine performance to V8"
Slower than V8 but faster than Python 3. But script performance in Sciter is not that critical (never been a bottleneck) for simple reason: script treated as a glue between native function calls. If you need something to run with bare metal speed - just provide native function(s) for this functionality. JS approach in this respect is simply crazy: to run something fast add megatons of JIT implementation and then another twist: WebAssembler. Why not just to compile what is needed with C++ into native code and call it? Again, Sciter is embeddable and extendable by design.
Consider the following:
Native UI: is a tree of widgets. Each widget has sematic properties / attributes. Each widget may have style properties (colors ,fonts, etc.). Each widget has exactly on parent and may have multiple children. There is an API for all of these.
HTML/DOM UI: Same as above, just replace "widget" by "element".
Could you explain then why one of these is "fundamentally unsuited" and other is a perfect match?
And just about all of these things are made worse by both the cascade rules and complicated precedence system of CSS.
This has nothing with the DOM (or HTML or CSS for that matter).
Yes, sometimes in desktop UI you will need to know exact element position/dimensions. That's why in Sciter I've added:
1. element.update(); method, it will force dimensions to be calculated at this moment.
2. element.onSize = function() {...} called when dimensions of the element change.
3. element.paintContent = function(graphics) {} called to paint the element on graphics. Dimensions and position of the element is known at this moment.
4. There is a Graphics.Text object that allows to calculate (not just render) text and glyph positions.
My main point with all this: it is a matter of API provided and has nothing with HTML/CSS per se.
For that matter, Flutter also uses DOM (tree of widgets, etc.). It is just that its style system is not declarative and misses cascading - for some reasons they decided to use WPF/XAML way of doing business. But we've already sang "Sic transit gloria mundi" to WPF ...
For the text editing... check html-notepad : https://html-notepad.com/ . Left sidebar (structure outline) is computed and painted in immediate rendering painting mode - when paintContent of the document is invoked.
Only with flexbox it became kind of usable for "apps". But still, the widgets are not native. You can keep emulating and emulating, but it's very easy to spot and quite frankly super annoying.
I see someone actually submitted the homepage 40 mins ago so I upvoted it for awareness. This is so feature complete I'm frankly surprised it hasn't hit the front page before.
Can the native UI framework do multiple windows? - Then React-Native can do multiple windows.
Rendering to a windows that isn't owned by the framework is what React-Native refers to as Brownfield apps. This is absolutely supported. For instance, Microsoft Office is using React-Native for some parts of their UI in Android, iOS, Windows and macOS. And the Office window is not created or owned by react-native.
I once used a native library I installed with iOS' native package manager, Cocoapods. I rendered a React Native view inside the native view, which was contained inside a react native view. The only limitation is that the two react native views used separate bundlers i.e. the two react native views can only communicate through the native platform, they couldn't communicate to each other via JavaScript.
STMicroelectronics uses it for almost all of their applications, which ship in one zip file with binaries for Win/Mac/Linux.
It ticks #1 and #2, but I don't know about #3.
Of course, I'm not sure if having web-like programming is your implicit #4?
My own experience with React Native has been nothing but terrible, but it will be interesting to see how all of this will play out in the long run.
If Google went away tomorrow, V8, Chromium and Blink would still exist, and Microsoft would be able to use all projects.
There's plenty of commits to V8 from outside Google. Blink is a fork of a fork of a twenty year old project.
My unconventional take is the real gains from react-native come from converting existing native projects, while leaving as much native code intact as possible.
The only cross-platform alternatives that I've seen in the ecosystem use either web or Gtk in the frontend, and both of these have a distinctly non-native feel to them.
Most cross-platform solutions are awful in at least one of those three, usually all of them.
QT Widgets, in contrast, do have native-looking widgets for Mac and Windows. You can use it with Python instead of C++, but it's a bit of a pain, and most of the Qt community seems to be moving towards QML, which is a far better developer experience.
https://github.com/wix/react-native-navigation is beautiful, it uses iOS' own navigation APIs, but it's a pain.
One other aspect is that Ionic React uses react-dom so it will be a pretty normal react dev experience compared to RN which isn’t 1-1 (CSS being an example).
> We are actively developing React Native for Windows...
> Mac
> Coming soon
So React Native for Windows.
I’m skeptical (though certainly willing to be convinced) because RN runs your JS application in a separate thread from the UI, with a rather expensive bridge sending JSON messages back and forth. That seems to me a poor design choice.
Browsers have the downside of working with the complex DOM that doesn’t map as well to native widgets. But browsers are mature and highly optimized. So I would guess that performance might be a wash.
* I think this is more of a selling point than a reality. I think in practice, to make a React Native feel and work well requires native platform knowledge.
But if you overload the bridge, you not only hit a bottleneck, you hit an async bottleneck between your UI code and native. Very rare for that to happen in my experience, and well worth the trade-off.
You can customize per-platform to provide a better experience than the web can offer.
It’s different in that it doesn’t use HTML or CSS (which is a major difference, sure).
Exactly like a web browser.
only a portion of the actual running code is JS
“Only a portion” meaning your entire React application! The native parts are the RN framework, any native libraries you’re using, and any native code you’ve added yourself.
What RN brings to the table, as compared to a browser, is a different layout model that’s simpler than the DOM and maps a bit more closely to native widgets.
It also has APIs for sending messages back and forth between JS and native code. That’s also possible with WebViews on all platforms, but RN has a more consistent API (at least on the JS side), so a decent amount of native bindings have been written by third parties.
I think you undervalue just how important this bit is.
It’s so easy to bind your own native code to react-native, it’s quite the game changer for those of us that have been managing two (or more) native code bases for different platforms for the past decade.
I have successfully merged two separate projects for the same iOS/Android app into one by simply writing JS bindings for the existing native code and moving all the business logic to react-native. I probably deleted more LOC than I wrote, and it’s still 90% native code- this is a GPU intensive A/V app.
I’m not a web guy so I can’t compare it to vanilla web react, but for native app development RN has been a huge productivity boost.
Exactly, in the sense that JS is a hosted language in both scenarios, but that's pretty much where the similarities end.
In a web browser, JS is the programmatic interface to behavior after the HTML and CSS are rendered. With React, a function of props that returns a JSX data structure is a declarative-ish interface to additional JS behavior. It's JS all the way down to the renderer.
With RN, JS is an interface to a lower level UI API on the host OS. A function of props that returns a JSX data structure is a declarative-ish interface to a bridge to that API, which performs the actual work.
It's hard to visualize the difference when just thinking of a static output, but easy once you start to think about user events. E.g. there is no `onPress` in the JS bridge for these APIs.
All of React is JS. A substantial portion of React Native, itself, is native. That's the difference.
> What RN brings to the table, as compared to a browser, is a different layout model that’s simpler than the DOM and maps a bit more closely to native widgets.
That's... maybe part of what would attract a dev to RN, but certainly not all of it. It also brings actual (not just close) native UI, with all of the performance and UX expectations that come with that. And it brings the ability to implement performance-critical logic in the native environment while sharing a lot of the rest of your logic with code for other environments.
> It also has APIs for sending messages back and forth between JS and native code. That’s also possible with WebViews on all platforms, but RN has a more consistent API (at least on the JS side), so a decent amount of native bindings have been written by third parties.
If I'm not mistaken, that's how RN works. (I could be mistaken.) In any case... that capability is hardly attractive unless the API is not just consistent internally, but with APIs on other platforms.
Worth it for some. Personally, I refuse to use any Electron apps because they have a highly non-native-feeling UX and because they're resource hogs.
This announcement excites me, because React Native is likely to be an improvement on both counts.
The UX still won't be quite as native-feeling as a single-platform app designed for that platform's unique idioms – but as long as it uses native controls under the hood, that's still 10x better than Electron in my book.
And even without the bloat of Chromium, an app written in JS is still likely to be slower than one written in, say, C++ or Rust – but most GUIs don't really need that level of performance. And at least on macOS, the competition is not C++ or Rust but Objective-C and Swift, which are both slower, more on par with JS in terms of performance.
Not making a point. Just couldn't resist.
Everything else is custom.
I mean, say what you will about the quality of even Apple's own Catalyst apps, but at least they eat their own dogfood (although with the unfortunate consequence of making us eat it, too).
There are so many different competing projects at MS to do practically the same thing, it'd be great to see RN for Windows and macOS used for something major from MS.
Flutter left me a similar impression.
I eventually ended up using Quasar https://quasar.dev/, which allows you to use one Vue.js codebase but deploy to Cordova on mobile and Electron on desktop. Vue is definitely not the prettiest solution out there, but I had to be practical and actually get the app out.
Maybe if I started the project one year in the future, the landscape would be totally different already. It's definitely changing rapidly.
We do pretty complex stuff with RN as does Facebook and it's been serving us well. I don't know why someone would want to use it with Windows, but this tells how far the project has gotten.
I would love to developed native, but you just save a lot (maybe half) time using RN if you need the app for both platforms.
I can copy couple of dlls in a project folder, and run npm / yarn install, but that is the most I am willing to do.
So, my question is: is there a VS Code / npm only demo?
As an ex-windows developer, turned react dev - I am excited.
> This repository is a working fork of facebook/react-native that adds support for the official React Native for macOS implementation from Microsoft.
Does anyone know when these changes are planning to be upstreamed?
1. the recent FB messenger desktop apps are RN.
2. they leverage work done in forks (like this one from MS) to achieve that.
(I mean, sure, it "just" runs Windows, but...)
> Mac: Coming Soon
You know what, I think I'll wait for Flutter Desktop, or see who wins true cross-desktop compatibilty since Flutter already has Mac support but no Windows.
Too bad Rust does not have something similar.
I'm really not sure what's relevant now and what was relevant 6 months ago. I'm genuinely curious, but it's pretty difficult to grasp and no framework homepage is going to tell you "Don't use me, I'm about to be a dead project!" and every developer will tell you their preferred framework is the best framework.
There are a bunch of others that are less popular such as Ember, Svelte, and Inferno which are also decent in their own right, but the ecosystem of libraries around them is smaller.
The most important libraries to know about in the React ecosystem are React-Router for routing, and either Redux or MobX for state management. There are other options, and for small apps you could get away without a state management library, but these are the mainstream options. I'm not super-up on the Angular/Vue ecosystems, but I believe they're more integrated (e.g. they provide more first-party libraries).
Almost everyone who is using these frameworks is also using either Babel or TypeScript together with Webpack for bundling. There are other options for bundling such as Parcel and Rollup, and again it is possible to get away without bundling or transpiling if you really want to, but Webpack is still the mainstream option for applications (Rollup is well-suited to libraries).
React-native is a different beast. It's a cross-platform mobile (and now desktop) framework rather than a web-based one. It uses React executed in a JavaScript VM to control rendering, but it renders native mobile UI toolkits. There are similar projects for Vue and Angular, but unlike the web versions which are competitive with React, they are nowhere near as mature. React-native's real competition for cross-platform mobile development is Flutter. Flutter is written using that Dart language, and takes a different to React-Native. Rather than compiling down to native UI widgets, it custom-renders everything. This makes it more reliable and consistent across platforms, but also more limited in what you can because you can't hook into the existing ecosystem of native ios/android libraries nearly so easily.
My subjective view on this is that React-Native is just about on the cusp of reaching maturity, while Flutter doesn't quite seem to have enough momentum to reach the mainstream. Although I'd love to be proven wrong on that one.
React has been a core part of the front end ecosystem for almost 10 years. Angular is more than 10 years old. Vue is the "new kid" on the block at about six years old.
React is roughly 10x more popular than Vue or Angular according to npm usage, has been far more popular in usage terms for many years, and continues to be growing faster than either Vue or Angular.
Complaining you can't figure out if React or Angular or Vue will be relevant in six months is a bit like complaining you can't figure out if C++ or Java will be relevant in six months. Yes, there is lots of advancement happening in the front end space. Yes, that's a good thing. No, it's not an excuse to act like you're paralyzed to understand the current state.
I was around in 2014, when angular 1 was starting to be a big thing.
If you look at reactjs on google trends, react gets its first bump in 2014-15, and then another one around 2017.
VueJs gets a huge jump in 2016-2017.
---
Java has been around for decades, has had much fewer changes, and is entrenched in a lot of code. In comparison, react has gone through some big changes in a very short amount of time, and most people use it to build SPAs that aren't usually mission critical.
It's still just running Javascript. The real difference is that it uses widgets that are native to the platform, instead of a browser engine/DOM.
Microsoft and Facebook attacking Apple and Google basically.
IMHO it's not a sincere effort to make a nice platform. It moves fast and breaks things in major ways with each minor point release, with the current excuse being that it's not at 1.0 yet. But it offers just enough to introduce FUD into the competitors' ecosystems. And that's the entire goal as far as I can tell.
If you value getting useful deep knowledge, stay away. If you want to play in the shallows and be patching stuff up all the time with JavaScript/TypeScript, React Native is an option.
Also Discord's iOS app is built with ReactNative, and it is a pretty feature rich application, seems like it works for those use it.