We're heavily considering just having a website next year with a mobile app using webview, and then native code for the native notifications, GPS and healthkit / health connect.
I feel like AI is changing the equation, its nearly better to write your business UI 3 times one for each platform.
It’s called a “WebView app” and you can get a really good experience on all platforms using them. Just:
- don’t make any crazy decisions on your fundamental UI components, like breadcrumbs, select dropdowns, etc
- add a few platform-specific specialisations to those same components, to make them feel a bit more familiar, such as button styling, or using a self-simplifying back-stack on Android
- test to make sure your webview matches the native browser’s behaviour where it matters. For example, sliding up the view when the keyboard is opened on mobile, navigating back & forth with edge-swipes on iOS, etc
I also went the extra step and got service workers working, for a basic offline experience, and added a native auto network diagnostic tool that runs on app startup and checks “Can reach local network” “Can reach internet (1.1.1.1)” “Can resolve our app’s domain” etc etc, so users can share where it failed to get quicker support. But this is an app for small-to-medium businesses, not consumer-facing, and the HTML5 part is served from the server and cached. I haven’t thought much about what you might need to do additionally for a consumer app, or a local-first app.
A while ago saw a blog link on HN that explained how Apple uses it everywhere and we never notice it because they are done well. Of course I can’t find that link now, I summon the HN gods…
On mobile the webview app experience is crap and it's immediately obvious that an app is not native. Simply nobody asks customers how they like it. The management assumes that as long as nobody complains and the users don't leave in droves, the experience must be impeccable.
> Definitely every one of these is sluggish at best on a very modern machine but they are also full of UI annoyances.
Aside from Apple’s apps (which imo are noticeably worse than the old ones, but that’s beside the point), what are some good WebView apps on iOS right now?
It doesn't look native but who even cares. I think when a UI sucks or is unintuitive or buggy then "it's not native" is a sort of catchall easy complaint. Native is a crutch. Sometimes it's a good crutch (accessibility etc). But that's more about developer efficiency and bare minimums of polish.
A webview app is by design bad. Webviews were made for one thing - web views.
(In the context of "Apple has a private CSS property to add Liquid Glass effects to web content")
There's some jump from _a property exists_ to _it must be used_, but a massive one from _a property exists_ to _Apple uses it everywhere and we never notice it because they are done well_.
Done well as in: laggy, non-performant, break OS conventions and you can see elements load with the naked eye?
See App Store as an example: https://grumpy.website/post/0RsaxCu3P or Apple Arcade: https://grumpy.website/618 or...
I would be interested in any links to Webview apps that run really well, I’ve never seen one that I’m aware of but so many that I am aware of and are bad!
And between average native and average web view - it is night and day.
99% of web apps in desktop browser are laggy. And on mobile it feels like crap.
Sure if you are an expert in top1% you can probably get it working really good. But this is true only for 1 in 100 if not less.
In case you're interested, the app is named "QuickÖV" - not relevant to anyone outside Switzerland, but just for trying it out: https://play.google.com/store/apps/details?id=com.billhillap...
This kinda shows you how much effort and experience goes into getting an UI framework right, and the long tail quirks (of which there are a zillion) matter for UX, and while I appreciate they took on the task of breaking away from the browser, it's understandable why someone wants to ship an app on time and budget goes with a web based solution.
https://github.com/aeharding/voyager
The app uses Ionic’s Capacitor, which to my rudimentary understanding is the webview-based upgrade of Cordova. I’ve had far fewer issues with this app than the likes of Bluesky (react native) and Discord (I think also react native but not sure).
The webview approach seems to be the only way for a one-person team to feasible provide a cross-platform app with an app-store presence. Another promising alternative to Capacitor is Tauri Mobile which does essentially the same thing, but mobile doesn’t seem to be a high priority for them.
- there's no touch feedback (ripple) on many of clickable components. Some that do have it look non-native, inconsistent and sometimes gets stuck
- the search bar on top app bar in `search` tab looks very non-native and non-standard (it's elevated on top of elevated app bar already)
- the lists look iOS-y, especially settings
- the settings list item has weird glitch where it loses background after touching (but not clicking)
- collapsing comments is pretty choppy (on a Samsung S25 so a pretty powerful phone)
- can't swipe down a bottom sheet (with post options/actions)
- it's just not android-y — the navigation is weird, the design is all over the place,
It's not unusable and it's a good tradeoff for a small team I guess. But this is nowhere near the experience a native app can provide, and has lots of small papercuts that would make for at least a slightly frustrating experience. It is a decent app don't get me wrong, but it's clearly not native
It does seem that many RN apps do React (not native) components when they need to do something custom, which may explain my sub-par, non-native experience with the RN apps I have used.
- "All toupées look fake. I've never seen one that I couldn't tell was fake." [1]
- All CGI in movies looks fake. It jumps out at me every time I see it."
- All WebView apps suck. Every one I've seen has a bad obviously-web-derived UI.
re: that last one though -- I'd at least acknowledge that WebView apps are roughly at the end of the early-2000's era of CGI: not exactly "The Rock in The Scorpion King" bad, but generally not at the level of Avatar or Les Misérables.However, from the user's side, this approach often results in a buggy, inconsistent experience that lacks the responsiveness and smoothness of a true native app that elusive "snappy" feeling (i know, I hate that word too)
Companies usually choose this route because it's cheaper, but that same "cheap mentality" often seeps into the overall product quality. Corners get cut, bugs get ignored, and long-term maintenance becomes a mess.
From a developer's perspective, it's a nightmare You're essentially expected to deliver on three platforms doing the work of three people for the same $ In theory, any web developer could handle it. In practice, you need to understand all the native platforms just to maintain some basic, stable integrations even with frameworks like React Native.
The result? Maybe 20% of your time goes into actual feature development, 30% into testing, and the remaining 70% into fixing obscure, platform-specific bugs while working overtime under pressure from cost-driven management.
In my experience, developers will do almost anything to avoid dealing with the native parts of this kind of setup those tasks usually get dumped on whoever is most "familiar" with native, because it's such a pain to handle.
And let's not forget QA testing across these hybrid layers is an absolute nightmare as well.
In the end, my view is simple: If a company can't afford dedicated native teams, they probably shouldn't build a native app. (Of course, smaller apps with limited complexity should be fine)
AVFoundation on iOS especially.
Or you ship your HTML/JS and not just embed a URL?
The platforms provide more than enough capability to build basic WebView apps with minimal effort, and usually the DX is good.
Native experience for users, where the app appears in their app drawer/library. The app doesn’t disappear randomly like shortcuts do on iOS (maybe this is fixed now?).
Better DX for certain features, like notifications, storage, control of caching, local network device access, etc.
And it’s still usable as a website for everyone else on any platform.
At least now I know who the offending devs are.
We have a React Native app that shares some code with a webapp, and that needs to do some geometry processing. So we're constantly playing the game of "will it interpret quick enough". Everything works fine in browsers, but in a RN app it often slows down to unusable speeds.
They always have to give up some basic or hidden conveniences that native controls get for free, so they always feel slightly different and "off" in a weird way which induces a constant vague annoyance while using them, like walking with a little pebble in your shoe, or a sitting in an chair that isn't balanced right.
It's funny how even after 50 years UI still isn't "solved" ..before writing a universal API, we don't even have universal consensus, or at least some kind of standards authority, on how controls should behave.
Hell not even users can’t agree, as would be seen on any comments about this topic, on stuff like whether lists should scroll up when swiping down, or scroll down when swiping up :')
To me, the web is the way around the app stores and codesign. I know how to visit HN on my iPhone despite there not being an official native app for it. It can work. The challenge is making it work in your particular case. Fear that the user wont know how to access the product seems to be a primary factor driving hyperbolic takes on how consumer apps must be built. Perhaps a bit of marketing budget (scan this QR code / visit this link) could eliminate a very expensive tech problem. Why fight visibility in the crowded App Store when there are countless other advertising channels you could pour your resources into?
> native code for the native notifications, GPS and healthkit / health connect.
Modern web can address everything here but the HealthKit item. You could consider handling this with a simple companion application that is exclusively about the collection and transfer of the data while respecting user privacy & consent procedures.
The downside is that the core of Qt is in C++, so it’s mostly seen (or used for?) embedded contexts.
I recently used Slint as well, which isn’t anywhere near as mature, but is at least written in Rust and has some type-safety benefits.
SwiftUI is pretty good too, and I wish I got to work on Apple platforms more.
To me, the simplicity of creating a “Button” when you want a button makes more sense, instead of a React component that’s a div styled by layers of CSS and brought to life by JavaScript.
But I’m kind of bummed that I started with that route (well, and writing partial UI systems for game / media engines a few times) because most people learned web apps and the DOM, and it’s made it harder to get the kind of work I identify with.
So it’s hard for me to recommend Qt due to the career implications…but at the same for the projects I’ve worked on, it’s made a smaller amount of work go a longer way with a more native feel than electron apps seem to have.
Anyone have any experience of doing this for a complex and long-life app?
Sounds like a nightmare that would increase friction and decrease development fun by x10 because of the huge overhead and tedium of having to keep your features and tests in sync across platform for every change you want to iterate on, and requiring developers be proficient at multiple stacks.
I get the usual complaints about bad webview implementations, but separate native codebases sounds like a prohibitively enormous tradeoff if most users only perceive the UX as being a little better than a good webview implementation. I feel like I'm missing something that native codebases is suggested as if it's a simple alternative, or this is coming from people that aren't actually involved in this?
Isn't reimplementing all your UI widgets, views, layouts and interactions for multiple platforms still a ton of work though? I'm not meaning people using things like React frameworks, but the suggestion of sticking to native only.
Also, you usually get better tooling in regards to instrumentation and the like.
When it comes to native stuff it get’s tricky. As always it really depends on the use case of the app. In our case we develop a navigation app using a native SDK to show a map + turn-by-turn nav + offline maps etc. This is probably the most non ideal use case for a hybrid app. We developed a few plugins to share data between js /native to initialize the map etc. However, the idea of sharing business logic is long gone. There’s so much stuff that’s happening natively and each time we implement it on Android, we have to switch to iOS and implement the Swift version of it.
Some others have also mentioned that a single person now has to know three platforms (iOS, android and Cordova (in our case with ionic + angular). This is true and the real downside. I’m quite familiar with iOS and android yet I’d never call myself a native iOS / Android developer. Yet, I’ve to write so much native code regarding permission handling, geolocation, threading (Ui/non-ui) and there’s always a ton to stuff happening from version to version (e.g. 16 KB Page Size on Android, iOS support for rotation the device/adaptive layout on iPadOS, etc). This is where a lot of time is lost. And the time is not only lost there but also with unmaintained outdated community plugins you suddenly need to understand and fix.
RN is a mess to get into, but once you've found a good stack you can really fly. We are working on a starter kit based off our experience that I think should represent the best possible starting point once it's released sometime before the EOY.
Lack of swipe for back on iOS is usually the easiest way to tell I'm looking at a web view.
But it's been about a decade so I'm due...
It's been a couple of years since I used it, but I think the Ionic framework has this feature.
Recent mid-tier phones are powerful enough that webview has a negligible impact on performance.
That said, platform lock-in is bad for business because it makes operations dependent on a single provider, but I have no delusions that a web front-end is better.
From an engineering standpoint, front-end web frameworks are less complete and require too many third-party libraries and tooling to assemble. From a UX standpoint, it's actually worse--almost every website you visit today spams you upfront with Google sign-in and invasive cookie permission requests that you can't refuse. But never mind that--from a purely business standpoint, a single platform accessible anywhere saves costs. Most importantly, however, the web is a "safe space" for deploying software anti-patterns without an intermediary entity (i.e an app store) to police your code, so you can do whatever the heck you want.
I'd wish for nothing more than the end of web and app front-ends in favor of purely structured data derived from natural language prompts by users. However, the more realistic mindset seems to be that: the front-end layer is such a high level of abstraction with a very low barrier to entry, so that its tech stack will be in constant flux, in favor of whoever's currently the best-financed entity seeking the most market share, the most developer mind-share, and the most behavioral control among its users.
4.2 Minimum Functionality Your app should include features, content, and UI that elevate it beyond a repackaged website. If your app is not particularly useful, unique, or “app-like,” it doesn’t belong on the App Store. If your App doesn’t provide some sort of lasting entertainment value or adequate utility, it may not be accepted. Apps that are simply a song or movie should be submitted to the iTunes Store. Apps that are simply a book or game guide should be submitted to the Apple Books Store.
At my last two jobs, when I did v front end work I had to coach designers through UX on a regular basis, because the designers did as much for the marketing department as they did for the development team.
Sadly, UX as a discipline doesn't get much love from most companies.
If you want to create good UX, I would look at whatever the big dogs are doing (Amazon, Meta, Google, et. al.) and not do that.
https://developer.mozilla.org/en-US/docs/Web/API/Web_Share_A...
https://developer.mozilla.org/en-US/docs/Web/API/Push_API
And not having to wait a week between bug fixes being deployed is a major selling point that native just can't compete with.
I still remember my Nexus One running flash!
Anyway, I wonder if the web path would’ve been the chosen one, how Apple would’ve played the web standards that are crippled today especially on Safari.
if you want to do something actually requires some compute, then suddenly this doesnt work so great
ex: youre prolly not going to want to edit images in JS
I saw another comment calling it "webview app", which is also valid, but we call it "hybrid app".
At the time such decisions are made, maybe the platforms couldn't do what was needed, but those platforms do tend to evolve, but not remain tracked.
Flutter to me has been one of the platforms that can quietly ship to multiple platforms as long as the parameters of what you're after can be accomplished in Dart, and if needed a bit of custom code for any particular platform.
React Native grew a lot this year and a lot of things got or will be improved and copied from Lynx or Valid:
- 3 modes of compilation (AOT, JIT) from Valdi will be in static hermes (RN) in coming months.
- native binding generation -> RN already have such official generator and also nitro/nitrogen, they also working on Node-API
- executing animation and JS code in different thread (Lynx.js) -> worklet library in RN from swmansion
- tailwindcss support (Lynx) -> uniwind in RN land.
I think Lynx.js maybe have better shot at React Native since they want to support other frameworks instead of only React.
[0] https://github.com/Snapchat/Valdi/blob/main/docs/docs/workfl...
And more importantly, Snapchat seems like an app which could highly benefit from tight integration with native features (eg. camera, AR features, notifications, screenshot detection, etc.)
These companies have super talented engineers and can afford to invest in skunkworks projects like these when they can’t find any suitable options in the market.
And then you call it simple?
As for the "success of Snap could be attributed to how pixel perfect the app is". I think the success of Snap can be attributed to a lot of things. But if you took a look at how unoptimized the Android experience was in 2017 when it was taking off I don't know how you could call it pixel perfect.
I don’t know a thing about Android camera SDK but I can easily see how this choice was the right balance for performance and quality at the time on old hardware (I’m thinking 2013 or so).
Users didn’t want the full quality at all, they’d never zoom. Zero latency would be far more important for fueling the viral flywheel.
Blame Google if you want to blame anyone. They could have mandated maximum shutter lag times (maybe they do now, I don't know).
// Import the StatefulComponent
import { StatefulComponent } from 'valdi_core/src/Component';
// ViewModel + State interfaces for component
export interface TimerViewModel { loop: number }
interface TimerState { elapsed: number }
// Component class
export class Timer extends StatefulComponent<TimerViewModel, TimerState> {
// Initialize the state
state = { elapsed: 0 };
// When creating the component, start a periodic logic
private interval?: number;
// Initialize the setInterval that will update state once a second incrementing
// the `elapsed` state value.
onCreate() {
this.interval = setInterval(() => {
// Increment the state to trigger a re-render periodically
const elapsed = this.state.elapsed;
const loop = this.viewModel.loop;
this.setState({ elapsed: (elapsed + 1) % loop });
}, 1000);
}
// When component is removed, make sure to cleanup interval logic
onDestroy() {
if (this.interval) clearInterval(this.interval);
}
// Render visuals will depend both on the state and the view model
onRender() {
<view padding={30} backgroundColor='lightblue'>
<label value={`Time Elapsed: ${this.state.elapsed} seconds`} />;
<label value={`Time Looping every: ${this.viewModel.loop} seconds`} />;
</view>;
}
}
https://github.com/Snapchat/Valdi/blob/main/docs/docs/core-s...As a solo-dev, I realize well that this project isn't for me. This could be a great tool for experienced folks who know what they are doing. I will stick to Tauri and React Native, it does 80% of what I care about with 20% of the effort. Or until someone builds a nice wrapper around this to make it easy to use (and also add targets for x86_64/aarch64 builds).
Not only are they often overengineered (at least, for the vast majority of people's usecases), but adopting them means you're adopting a consistently moving target who's priorities are chasing whatever trend BigTech has convinced itself is The Next Big Thing(TM) - often reinventing the wheel yet again in the process - whether you're on board or not. Not to mention possibly getting caught up in change-of-licensing issues (eg Terraform switching to BSL/BUSL) or cult-of-personality drama by the maintainers (Wordpress)
There is a place for these frameworks, even beyond their use in the house they were built at and for, but for the vast majority of usecases, they're not merely overcomplicated, but continually changing in their complexity to boot.
For example, when a user clicks a button, how many calls and moving pieces are involved between the click and something happening on the screen as a reaction to that click.
Often it's a good indicator of how deep the rabbit hole goes.
How hard could it be?
Most apps are UI, remote requests and maybe some storage. What do you put in the common core? Android does HTTP requests one way. iOS does them another way. You go for the lowest common denominator an implement a third way, using libcurl or something?
Or do you just put business logic in the common core? Is there really that much business logic that doesn't issue requests or access a database?
> What do you put in the common core? Android does HTTP requests one way. iOS does them another way. You go for the lowest common denominator an implement a third way, using libcurl or something?
If it's really functionality that cannot reasonable be shared don't share it.
It's probably more work to maintain bindings to a single API client in the core and fiddle with all the details of not using the native HTTP client implementations that it is to implement the API client twice.
Writing the API client twice is boring, but that's a good thing.
> Or do you just put business logic in the common core? Is there really that much business logic that doesn't issue requests or access a database?
The shared core is optional. You might have the need for it, then it's a good solution.
For an app like snapchat you'd probably share the video effects and have that in your core library.
Every time I see a new project like Valdi, I am hoping for something that is truly magical and cross platform, but I'm always steered away by comments like yours and people saying "you have to do native".
For context, I am a dev, and I've done RN apps in the past.
How many people do you need to build JUST the native Android and iOS app for snapchat?
Is the "single" codebase really worth all the added complexity and additional risk?
I'd always go the native route if the user experience is business critical.
If you want to simplify development of a cross-platform app, your work should start by architecting the software in a way that the core business logic is agnostic to the user interfaces. Then your web, mobile, and desktop GUIs, CLI, TUI, API, and any other way a user interacts with your program are simply thin abstractions that call your core components.
The complexity of each UI will inevitably vary, and it might not be possible to offer a consistent experience across platforms or to leverage unique features of each platform without making your core a tangled mess, so this is certainly not "easy" to do in practice, but this approach should avoid the bulk of the work of targetting individual platforms than if you had done it any other way. It should also avoid depending on a 3rd-party framework that may or may not exist a few years down the line.
One extra clarification: If the quality of your app is business critical you should really use the native UI toolkit to offer the best platform integration and user experience.
If your app is not business critical (you just have to offer it - example: dishwasher app, ..) you might get away with using a cross platform toolkit like flutter or react native. But even then this adds a 3rd party dependency as you mentioned which adds risk.
Writing an App in Swift on iOS is boring. The same thing is true for writing an Android app using Kotlin/Java. This is a good thing. Now your developers can concentrate on shipping great features.
I’ll take it
> it compiles directly to native views
There are significant trade-offs with this compiler at the moment: it uses much more binary size than minified JS or JS bytecode, and performance improvements goes from 2x to sometimes zero. It's a work-in-progress, it's pretty far along in what it supports, but its value-proposition is not yet where it needs to be.
Concerning that there's no mention of Swift there. Or SwiftUI.
Using frameworks is expensive by orders of magnitude. It’s additional code which greatly increases tech debt and slows the execution time of the given product pretty significantly. Think about it like this: a business with high confidence developers can ship a new SPA in a tenth of the time just using vanilla JavaScript that fully renders to screen with complete state restoration across the internet in less than a quarter second. That also means the business saves boat loads of cash by shipping faster, experimenting against its user’s behavior, and needing only a quarter of the headcount. So, where do you find these people and how do you retain them?
The economics are pretty simple and completely offensive/hostile to the developers. It’s ultimately about hiring and firing. Developers are a cost center to the business so the goal is to always eliminate training and turn them into a replaceable commodity. That’s it. That developers believe this is somehow a great empowerment is a double win for the employer.
The reason a company might introduce a new framework is because they encounter a problem not immediately solved by existing frameworks. The more frequently that same problem occurs the more a new framework pays for itself.
The only FAANG scale companies that adopted React Native are Microsoft and Amazon because they aren't directly competing with Meta.
Color me yellow.
There's also views I can get into which I can't figure out how to leave, so I force close the app to get back.
I don't necessarily think that's a flaw of the framework, just how Snapchat designs their app.
When they first introduced video calls, schools had to close for a day.
Imagine then you come here and see someone calls it awful. Can't help but think its just an instance of "old man yelling at clouds".
By definition, the first app someone uses will be from their POV the most intuitive app ever. It will also be the least intuitive app ever.
xD
It's mostly subjective when talking UI, and a lot plays in too regarding the lack of competive platforms with different UI's.
If all the other apps look similar its because they copied it. This is like calling Citizen Kane boring.
> introduce feature
Phwoar, ground breaking UX design there!
> When they first introduced video calls, schools had to close for a day.
Which schools, where? Are they in the room with us now?
> For people who introduced themselves to tech with snap as one of their first apps, its the most intuitive thing ever
Point camera. Press button. Pick users.
Gotta try real hard to screw that one up, UI wise.
Seriously, if there’s an app that sticks in my head for being noticeably laggy, you couldn’t pick a better example than Snapchat.
I presume this is a Text UI. How does it compares with ncurses and termcap ? /s