As we are nearing the initial launch of our first Web product, we have settled into a pretty interesting Web tech stack – I wanted to write up a quick overview. I am a big believer that both “the tools don’t matter” and “the tools matter quite a bit” are true at the same time. (See here.)
What matters most to us is: launching the easiest way to quickly share anything securely with anyone. Sharing is still too difficult! We are building Shareup to help teams collect, organize, and make sense of the files, links, and services they use to get their work done everyday.
Also, we are hiring a Web Engineer. If you are an experienced frontend engineer and are excited to make it less stressful for everyone to share, then please reach out – I want to talk to you.
A few scenarios that literally happened to me in the past few months:
- I got these 20 photos I took on a trip and I want to get them over onto my friend’s laptop, AirDrop isn’t working, why is this so hard?
- I need to email my passport, but I don’t want to just attach it to this email for everyone between me and the recipient to see in the clear, how can I send it securely?
- I need to discuss a few links and a few PDFs with my colleagues real quick to make a decision, how can I gather them all into one place and quickly go through them with my teammates?
We are making some key technical bets for our Web stack so we can solve these problems for ourselves and for everyone else on any device with a modern Web browser. Since we are a small team, we can move fast and make a few more risky bets on newer or emerging tech.
Our key bets for the Web are:
- Offline-first experience
- Mobile-first design
- WebSocket-only API
- TypeScript and Deno
- Preact and SSR
Betting on WebAssembly
Keeping your data private is a top priority for us. We’ve seen too many companies disclose breaches, too many accounts getting hacked, and too many photos and documents being leaked. Every photo, link, PDF, note, and video shared through Shareup is end-to-end encrypted – we cannot read them. We store encrypted blobs of data which look like random noise to us.
We are betting that WebAssembly is the best way to get our compiled encryption code into the browser. And, to make sure our encryption works exactly the same everywhere, we share the same
.wasm binaries across all of our clients and services.
In the near future, we expect more capabilities and features to be shared across our apps and services with WASM. This is one of our biggest bets for 2022–2023 🤞
Betting on an offline-first experience
We expect the apps we use to be super responsive – any perceived lag causes doubt about the reliability of the service. By building our Web application with an offline-first philosophy, we are prioritizing updating the local UI as quickly and smoothly as possible without losing any data.
To be an offline-first Web app means we are betting on IndexedDB, Service Workers, Web app manifests, and other PWA tech. All of which are exciting and frustrating 😅
Choosing to upload a file means saving the details into the local IndexedDB first. Inserting a new record into the object store will wake up an async process to start uploading the file to the remote server. When one returns to a shared space later, it can load instantly from the local IndexedDB and then, after the UI is interactive, catch up with anything new from the remote server.
A Service Worker helps us serve cached content, including the Web app itself, even when offline. We also use the Service Worker to centralize database updates, centralize WebSocket communication, and notify all tabs about underlying updates so they are all always as accurate and up-to-date as possible. The Service Worker also performs any background tasks like encrypting or decrypting files, fetching link metadata, or anything else that might interfere with a snappy UI.
Betting on a mobile-first design
A mobile-first design and implementation means: the default is mobile, everything else is enhancement. This means the mobile view is never without an important feature; instead every feature finds a home on mobile first. Then, for larger viewports or more sophisticated browser clients, we can use breakpoints and modern styling like CSS Grid to relayout and reveal more.
Most Web apps start as “desktop size” and then attempts are made to shrink it down and cram it into a smaller viewport for a phone. We think this is the wrong direction: shrinking and removing never works out as well as expanding and enhancing. Also, starting with the baseline of a low-powered, network-constrained device means we design and build our app to be simpler, faster to load, and completely usable for everyone while on-the-go.
Related to “on-the-go,” I also want to mention that an interface which is usable in one hand on-the-go is also more usable for someone actively caring for a child in one arm or anyone else who doesn’t have full use of both their arms or hands at the time. This is just one example: we are striving to use semantic markup by default, ARIA when needed, test with assistive devices and with those who use them, and make sure we can help the largest number of people share anything with anyone, anytime, anywhere, in any circumstance.
Betting on a WebSocket-only API
To be more specific, we have a Phoenix service which only exposes a Channel API. Any links added to a shared space, all file uploads, and all presence updates flow over the WebSocket connection between the browser and our elixir service. Phoenix’s Channels have been super rewarding to work with and we are betting we don’t need REST. The instant communication sockets provide is key for Shareup to be the fastest way to share files and links.
Betting on TypeScript
For our project, TypeScript has been invaluable. Every line of code intended for the browser is TypeScript. We are betting it will (and already has) help us write and refactor more confidently, ship apps with less errors, and have code that is more self-documenting. This is a no-brainer for us. And while TypeScript can sometimes be a little frustrating, we are grateful we get to use it everyday.
Betting on Deno and esbuild
Our favorite language server and runtime for TypeScript is most definitely Deno. We are using Deno to lint, format, type check, and then bundle and serve all our browser-destined code. We also find ourselves writing most of our “scripts” to run with
deno these days, instead of
We also are betting on esbuild to prepare our Typescript for the browser. It’s incredibly fast, easy to extend, and was very easy to integrate into our existing TypeScript + Deno mono-repo. It’s used by Vite and other bundlers, so we feel pretty good about it 🤓
We are not using
node, or related tech for our main app at this point. We do have a couple Cloudflare workers where we use
wrangler which does use
npm. We are not against
node, we’ve just found our
deno setup to be easier to maintain and faster to develop in.
And we can ship our bundled Web app, the TypeScript Web server code, and the
deno binary itself all combined as our deployment artifact, which is very small and super cool. 😎
Betting on Preact and SSR
We are using Preact. We love functional components, we love hooks, and we love the small size of Preact. We care about every
kb we transfer to the browser and we care how complex that code is to interpret and then run. We are going all-in on
preact-iso for server-side rendering and hydration.
We are not able to do everything server-side, because all shared files and links are fully end-to-end encrypted; so we get prepared to quickly light up the UI, connect to the WebSocket API, and quickly download and decrypt what is necessary to show. The increase in privacy is worth it for this tradeoff. 🕵️♀️
This will all change, I’m sure
We are not dogmatic about any of these choices. If something would help us better serve our customers, then we will switch to it. This is a snapshot of where we are today at the beginning of 2022.
And we are hiring. If you are excited about helping people more easily share and about the tech we are using, then please reach out about our Web Engineer job – I want to talk to you. We are a small team, we can move fast, and we are making some exciting tech bets that larger companies/teams probably can’t afford to make. 💪
And finally, what tech are you excited about in 2022? Tweet @ me 🐦