Ask HN: What's your favorite way of getting a web app up quickly in 2018?

542 points by westoncb ↗ HN
I am still frustrated with the amount of incidental complexity required whenever I want to do this. My latest attempt was to use a Digital Ocean droplet with Django pre-installed. I guess the biggest issue there was setting up something so that I could easily deploy my local version to the droplet (ended up using git/Github), and ensuring those two environments were in sync. I looked into Docker in some detail about a year ago, and I think it's the only pretty good solution for this I've come across—but there's a steep up front cost in learning/setup etc. (or so it seems).

What services and technologies do you use when you'd like to quickly build a web app which may never be more than a prototype, but may also turn into something real? A big aspect of what I'm wondering is about automatically setting something up for keeping local/production environments in sync, quickly deploying to production, and not having to mess with a bunch of server configuration things, user accounts, security, etc.

568 comments

[ 2.4 ms ] story [ 307 ms ] thread
create-react-app
Same. As for deployment depends somewhat on the back-end but I tend to use elastic bean stalk if I’m aws.
That's purely front-end tech if I'm not mistaken. My question here is primarily about the back-end aspects of a project (especially syncing local and production environments, etc.).
Django. Use Cookie cutter and call it a day.
Imo Docker doesn't have too high a learning curve at the start. It's just when you move up to docker compose, Kubernetes that it can be overwhelming.

My opinion is that when you're starting out, just go with a PaaS like Heroku. You can simply maintain a separate dev/prod branch and it'll automatically update the server.

All the issues you mentioned can be solved it just takes some investment somewhere (time if you do it today yourself / money to pay a PaaS or someone else to do it).

We personally use Kubernetes to solve these issues since we get stateless builds and simply have environment variables that change things like database connections, api keys, etc between our various environments. But again this took a few weeks to setup.

Heroku and node with any frontend framework of the moment
1) ASP MVC .NET Core 2 project 2) Get a linux vm 3) Write a WSL Script to push to linux vm (lftp + sshpass)
ASP.NET Core in a (Linux-based) Docker container and Amazon Elastic Beanstalk works pretty well.
Linux support was the best thing Microsoft have done for .NET.

It's now a viable option.

1. flask-base for back-end

2. create-react-app for front-end

3. digital ocean for hosting

I just cp files from local to server and use a couple different bash scripts for dev vs prod.

I write the server-side in Go, cross-compile to a Linux binary, and set that up as a service on a vanilla Ubuntu box (usually Digital Ocean). Deploying a new version is a matter of sftp'ing the new binary (and any templates, images, etc) over the top of the old one and restarting the service.

If I need a database then I use Postgres, and the setup for that can be a pain, so I get it documented/scripted using Ansible.

If I need something more complex than plain HTML on the client side then I use a Makefile to synchronise Webpack + Babel + React (and the hot reload during development), and the compiled bundle.js becomes another file to copy over.

I realise it's not very 2018, but to be honest I've kinda lost the will to live over learning anything more meta at this point.

This is about as 2018 as it gets. Go and Rust are the only modern languages where you don't have to second-guess the stdlib for bad choices (looking at you php/ruby/javascript/etc..) yet provide amazing performance.

Backend: Go (optional embed db: ledisdb / boltdb / leveldb / rocksdb / etc...)

+

Frontend: create-react-app / create-react-native-app

I find Ruby’s stdlib a pleasure to use.
How many web apps can you name that don’t rely on any external gems? Packaging that mess is a pain in every scripting language.
Anything that runs on JRuby can be packaged as a single file.
And even with MRI, it's not as painful as people make out. Set `$GEM_HOME`, `bundle install`, tar up your app and the gems, stick them on the server.
How far do you make it writing a web app in rust or go without pulling in external packages, then? Or a front-end using only javascript and html?
In Rust, it’s pretty quick. You could write a server yourself, but it would take a lot of work. It’s trivial with a package though.
Steve, what is Rust's equivalent to Go's cross-compilation-- plain old cargo build?
$ cargo build --target=TARGET

a list of default targets-- $ rustc --print target-list aarch64-linux-android aarch64-unknown-cloudabi aarch64-unknown-freebsd aarch64-unknown-fuchsia aarch64-unknown-linux-gnu aarch64-unknown-linux-musl arm-linux-androideabi arm-unknown-linux-gnueabi arm-unknown-linux-gnueabihf arm-unknown-linux-musleabi arm-unknown-linux-musleabihf armv4t-unknown-linux-gnueabi armv5te-unknown-linux-gnueabi armv7-linux-androideabi armv7-unknown-cloudabi-eabihf armv7-unknown-linux-gnueabihf armv7-unknown-linux-musleabihf asmjs-unknown-emscripten i586-pc-windows-msvc i586-unknown-linux-gnu i586-unknown-linux-musl i686-apple-darwin i686-linux-android i686-pc-windows-gnu i686-pc-windows-msvc i686-unknown-cloudabi i686-unknown-dragonfly i686-unknown-freebsd i686-unknown-haiku i686-unknown-linux-gnu i686-unknown-linux-musl i686-unknown-netbsd i686-unknown-openbsd mips-unknown-linux-gnu mips-unknown-linux-musl mips-unknown-linux-uclibc mips64-unknown-linux-gnuabi64 mips64el-unknown-linux-gnuabi64 mipsel-unknown-linux-gnu mipsel-unknown-linux-musl mipsel-unknown-linux-uclibc msp430-none-elf powerpc-unknown-linux-gnu powerpc-unknown-linux-gnuspe powerpc-unknown-netbsd powerpc64-unknown-linux-gnu powerpc64le-unknown-linux-gnu s390x-unknown-linux-gnu sparc-unknown-linux-gnu sparc64-unknown-linux-gnu sparc64-unknown-netbsd sparcv9-sun-solaris thumbv6m-none-eabi thumbv7em-none-eabi thumbv7em-none-eabihf thumbv7m-none-eabi wasm32-experimental-emscripten wasm32-unknown-emscripten wasm32-unknown-unknown x86_64-apple-darwin x86_64-linux-android x86_64-pc-windows-gnu x86_64-pc-windows-msvc x86_64-rumprun-netbsd x86_64-sun-solaris x86_64-unknown-bitrig x86_64-unknown-cloudabi x86_64-unknown-dragonfly x86_64-unknown-freebsd x86_64-unknown-fuchsia x86_64-unknown-haiku x86_64-unknown-l4re-uclibc x86_64-unknown-linux-gnu x86_64-unknown-linux-gnux32 x86_64-unknown-linux-musl x86_64-unknown-netbsd x86_64-unknown-openbsd x86_64-unknown-redox

Thank you
Note that you also may want to use xargo or cargo-xbuild to build other custom targets, and rustup to fetch the stdlib for the targets listed above.
Aren't there also linker issues with cross-building for some targets like i686-pc-windows-msvc? At least, I don't think I ever got it to work properly but I don't recall what the exact problem was.
I never use server-side external packages when writing web apps (well, except the bcrypt crypto package, which is an official package but not technically part of the stdlib yet).

Dependencies are evil.

> as 2018 as it gets

sftp'ing a binary to your deploy target? That's more 2008 iyam...

I second this; Go + React.js (Vue.js in my case)

I talked about it just a couple of hours ago [1].

[1] https://news.ycombinator.com/item?id=17215658

That's interesting... I think I'll spend a couple of days playing with Vue to see if I can get rid of Webpack and Babel, because they're an enormous pain to set up (especially as they keep changing their config schema every major version release - I think I've climbed Webpack's config learning cliff three times now).
React doesn't need webpack or babel. People just see lots of benefit in using them, but there are tutorials out there on how to use just React.

It can be as simple as a script tag at the bottom of your html and then writing ES5 React.

Vue apps depends on webpack as well. But the vue-cli makes the whole set up a breeze. Especially v3 (currently in beta)

If the website you're building is simple you could even have vanilla html pages then attach vue to the divs that need that extra interactivity, then you won't any fancy loaders.

I try dozen of tools for a cross-platform app and finally settle on use vue.

Every time I use node and look at his insanity and get depressed.

So, I dislike STRONGLY the use of Webpack and friends. Is a chore because JS is even more nuts now, and everything assume you want node nonsense everywhere.

So, I persist and do this:

I introduce:

> Non non-sense javascript front-end setup with vue

https://gist.github.com/mamcx/1d3aa692b0d34b0fae696c12292a1a...

Using local .js/.css files downloaded from a cdn, then using cat to concat in the correct order all the deps, and finally let to build your css/js as you please for your logic.

Build time is zero after the first try.

P.D: Maybe using unix pipes I could minimify and stuff like that, but I don't need that.

If you just have a Vue file script tag in your document, you're good to go. If you want single file components, hot module reloading, Babel features, etc, you'll need Webpack. Luckily, the current and beta versions of the vue-cli make these non-existant problems. Just install using the cli and it's good to go, no setup needed.
How do you handle server side rendering? This is one of the reasons I chose to go full Node+React.
Vue also has server side rendering.
Check out gatsbyjs.org for server side react rendering.
nuxt.js is an all in one vue framework that has ssr and a really cool file based routing functionality
How is this setting things up "quickly" when OP is asking to limit complexity? You're suggesting:

1. Server side in Go 2. Cross-compiling it 3. sftp'ing and restarting the service everytime 4. postgres 5. ansible 6. Makefiles 7. Webpack 8. Babel 9. React

Writing web servers in Go is extremely easy. https://golang.org/doc/articles/wiki/

Cross-compiling with Go is done by setting two environment variables. That's it. This is not like the mess of C++ cross-compiling. In LiteIDE it is simply a matter of choosing Linux from a drop-down: https://www.wut.de/pics/screenshot/e-505ww-07-pide-000.png

SFTP is not exactly hard. Nor is `nohup ./server &`.

From 5 on I agree though - is that 4 build systems? Insanity. I would just make a static web page with normal HTML forms or whatever and Go templates. If you really need client-side Javascript, I'd just use jQuery, or something similar and lightweight like minifiedjs.

yeah, I use straight HTML wherever possible. But for some things it isn't possible, or suitable. I'd love a simpler client-side environment. Any suggestions welcome... I'm looking at Vue.js now, recommended from comments here.
I've enjoyed using Elm for client side development.
For me this is the response to 'how do you build stable/scaleable/.../good web apps in 2018', but sadly not to 'favorite way of getting a web app up quickly in 2018?'.

The whole process of starting a new VM for every little project seems to me like overkill and developing components if you just want to get a prototype out the door can be difficult as the components will most likely have such a poor quality that you can't reuse them for anything else.

With that said, I am 100% pro Golang Server + Vue.js UI when it comes to building something which will be definitely more than a prototype (no shortcuts taken).

Your start is good but you add complexity on top of it. Install Golang on your VPS, clone the source code on it and compile it there instead of messing with cross compilation.

Also use sqlite to avoid the pain of setting up a SQL server, there is no need for it.

You can then easily get systemd to supervise your binary.

This is how I host all my web apps, the main difference is that I don't use Go but Nim. If you want a great framework match up then check out Jester + Karax, see how I developed the Nim Forum using this combination.

Better would be to just use docker.
Please explain. I still don't understand the use-case for docker...

How is docker going to make my life easier in this example?

> instead of messing with cross compilation.

To be fair, cross-compilation in Go is as simple as setting and environment variable.

Why put the source on the VPS? Go cross compilation is much easier then you make it sound.

    GOOS=linux GOARCH=amd64 go build
Nim can't beat that.
That's awesome, I didn't realise it was that easy with Go.

Of course, I would say keeping the source on the VPS is just as easy.

And what about zero downtime deploy (upgrading the app binary and updating the database schema)? It's difficult to do without some kind of reverse proxy and without a database server.
How often is that really required? OP asked for a quick deploy, for most apps it's enough to put the db into read-only mode and then update the schema. Upgrading the app binary is as simple as replacing it on the file system and then restarting the service.
The more often we deploy with CI/CD, the more we need zero downtime deploy. Putting the DB in read-only mode is not that simple, because the app needs to be able to work in a degraded read-only mode.
Yeah DB migrations are a pain in the bum. I do them manually because I still haven't found a tool that handles them properly.

But by the time there's significant data to migrate to the new schema, any schema change is usually due to a major version change or feature implementation, and the migration is part of a wider pain-in-the-bum situation.

How is it possible that you sftp the new binary while the sever is running? It won’t let you because the file is in use.
Unlike windows, Linux allows you to delete a binary while it's running (the binary file is not locked).
whats the level of your app's complexity?

Your description would seem good for something management etc has down on paper / a design document.

I think Dokku solves a bunch of your pain points: https://github.com/dokku/dokku
Dokku is _preeeeeetty_ good but you kind of end up messing around on the server eventually to get things working, or fix things, etc.

If you're into that, or have CPU/RAM requirements that would be prohibitively expensive on Heroku then give it a try (I run it for a couple things on a cheap but powerful dedicated machine). If you're just doing something simple it's probably not worth it, just get a hobby dyno and go that route.

Zeit Now, without a doubt.

1. npm install -g now

2. run 'now' command in the folder containing your app files

The files are uploaded, your app is deployed and your clipboard contains the URL. So simple it's like cheating.

https://zeit.co/now

I was expecting to see more of Now in these comments. I don't have any real experience with it but it did seem like it would make deploying as simple as possible. Care to share any of your experiences with it?
1) Spring Boot on Google App Engine free tier

2) Managed Postgres on GCP/AWS

3) Frontend framework of the day, like React or Vue.

4) Take 1-2 hours in the beginning to set up ci/cd (like Circle) to make things 10x more convenient.

>4) Take 1-2 hours in the beginning to set up ci/cd (like Circle) to make things 10x more convenient.

Can you expand more on what you do here?

create-react-app + netlify on the frontend. For the backend services, kubernetes on gcp with Ambassador from Datawire. It’s an extremely solid and easy to use gateway based on the Envoy load balancer. I have a few templates I’ve created that has reduced creating a new app/service down to a few keystrokes.
Heroku is still a great choice if you're willing to pay to never think about infrastructure.

On the other hand if you're willing to ask for help there are plenty of freelance IT admins who would set up a digital ocean box with the DIY equivalent of Heroku.

Not trying to be snarky but... how is it cheaper to hire a freelance IT person to set up something for you, and help you when it breaks/changes, than $7/mo for Heroku?
The issue with Heroku is it rapidly gets more than $7/month if you hit any sort of scale.
In my experience this is vastly overstated.

Also, just because you use Heroku for your app servers (dynos) doesn't mean you have to use it for everything.

Absolutely. We went from free tier to about 100/month in nearly no time with Heroku. It’s worth it though. Heroku takes care of all sorts of stuff, and that fee is still cheaper than hiring a sys admin for a small business.
That is quite literally the price you pay for convenience. In many cases, that's a very rational tradeoff - your time is better spent on developing and marketing your app than dealing with devops. If your Heroku bill is a relevant business problem, then you're probably grossly under-charging for your app.

I think the main competition for Heroku these days is AWS and GCP. The workflow for deploying directly to managed cloud services has improved drastically over the last few years, so you might not need the niceties that Heroku offer.

I would not recommend this unless you hire these people for a regular maintenance role.

Leaving a box with no monitoring and no on-site skill capable of fixing it is a bad idea. That box will explode at some point and it's going to explode at the worst possible moment, and you'll loose tons of business (and/or data) while you scramble to get someone to repair it.

Unless you have people ready to jump in and fix it should it break, don't risk it and just let Heroku handle it.

Strongly agree. I loved AWS Lambda both for pricing and for developer convenience/efficiency, but managing the network infrastructure beneath it finally irked me too much, so I switched to pushing a Docker container to Heroku and haven't looked back. I am tempted to believe that a lot of teams might be forcing themselves into over-engineering/overkill to jumping right to AWS where it's not needed.

I have read similar comments to the ones here about scaling and cost, so I might bump into that at some point.

Rails + whatever framework works for the desired frontend
I use Swagger/OpenAPI to define the REST API, which is fast and makes the API including the main data types easily visible.

To implement the server side I typically generate Java JAX-RS skeleton code that can run in Jetty using Swagger codegen. You fill out implementation code and the app is off and running.

On the client side I generate Angular client stubs using Swagger codegen, then fill build services and UI components on top. For CLIs or other tools you can take a similar approach or just write the REST calls directly.

Code generation from an OpenAPI spec makes this process a lot quicker as it takes care of most of the boilerplate code necessary to process REST requests. It's especially helpful for making quick changes and also helps you to get to a stable, easily understandable API which is necessary if you decide to turn the service(s) into a real product.

Docker is incidentally a godsend for systems with multiple services, especially if you work in polyglot environments.

ember new my-app

Yes Ember is still great. Ember data has gotten bloated though so I say pull that shit out IMO unless you are really used to it.

Ember v3.0 is all modular now, so you can just strip out modules until you get down to Glimmer. Versus React or Vue where you start with basically nothing and build upwards.

Exact opposite philosophy, but way faster for building 90% of CRUD apps.

The most recent one I created was with Laravel hosted on Fortrabbit. If you want it to be even easier, try Laravel Spark. It is really easy to launch something simple.
Quickly? Firebase + React.

Seriously, don’t overlook this combo. Auth just works. Hosting built in, no backend or database server to maintain. No API, just subscribe to a collection right from the view. It just works (and is easily swapped for the real deal if you need it).

I made a guide/boilerplate to show you how (includes auth, CRUD, full text search, stripe subscriptions):

http://getfirefly.org/

Too expensive to be worth it. I'm totally fine with outsourcing stuff that is difficult and third parties can do better, but in this case the amount of stuff you're playing egregious "cloud" pricing for is too much. Just spend a handful of days learning one of the open source stacks and you'll be set for life. It's totally worth it assuming you'll be making more than 1 app ever.
Guess it depends on what you consider expensive.

For me, time I’m writing unnecessary code or learning libraries I don’t already know is time I’m not spending thinking about the product. I’m a designer who just wants to ship.

I am open to suggestions though. What would you recommend for, say, auth instead? I’ve tried rails, Django, node/mongo, etc; even hosting a small db on compose.io comes with a chunky base fee, and I still have to do way too much work for user accounts/search/APIs/ORM. There’s a reason Firebase is popular with the yoof.

Change my mind though!

Opensource alternative to firebase: couchdb . Less features but the essentials are there...
If you use couchdb+rxdb, you have the same subscribe-to-collection thing but without the google lock in
Firebase's free tier is more than enough to play with an idea, and the next tier up is (100k concurrent users) $25/month ... if that's too expensive then there's something very wrong with your pricing model. Obviously this assumes you're not storing much data per user - you wouldn't build a imgur clone with it - but it's not that expensive for any typical SaaS app.
And it's actually way cheaper for small apps if you "upgrade" to the Blaze plan and do pay-as-you-go billing. I often pay between $0 and %0.05/mo...

Full pricing: https://firebase.google.com/pricing/

Concurrent users are not the only limitation. Your app needs to fit the bandwith limits as well. I had to shutdown a very simple app with a few users because of ridiculous billing.
"Just spend a handful of days learning one of the open source stacks"

Sure, but which one? :)

While firebase has an expensive first tier, Firestore bills more for what you use, like AWS does.
I was gonna say the same thing. It’s cheap/nearly free if it’s just a little side project or low traffic thing. And a joy of a stack to work in.
This.

Maybe I am biased because I develop most of my applications in React. But if you don't want to bother with any backend application and just want to get out quickly, build your React application with Firebase. That's how I do it and that's why I also covered my whole boilerplate process in a comprehensive tutorial [0].

- [0] https://www.robinwieruch.de/complete-firebase-authentication...

yerp, by 2018, UI + SaaS backends is often the easiest way to get something deployed ... provided you want to deploy essentially the same thing other people already have + some customization ..

.. what's going to be neat to see is how that "essentially the same thing" changes over time.

deepstreamhub.com is another neat SaaS that's worth looking into for some cases that Firebase might not handle as well ... there are probably yet other SaaS products that cover other specifics and will be still more in the future..

.. obvious mention re. SaaS products is that they could evaporate at any time. warranty void where prohibited. all states except ... idk, AK, for some reason.

Just stripe subscription? Customers of my consultancy also require Bitcoin, Wire transfers and other payments. We use http://killbill.io/ now. It supports multi tenancy.
I'm having trouble building with this. Can you elaborate a little bit more about the steps after adding adding all three project. I can't understand this

>> " Now let's connect our databases to our app by adding their "keys" to our app's environment ("env") files. You should generally keep connection keys like this secret, so first we'll rename our environment files to keep them from getting committed into git (the new filenames are listed in .gitignore). "

I just dropped firebase after nearly a month of development. Firestore lacks so many features that i consider basic. For example you can't even do a count query on the db and have jump hoops to even achieve this simple feature.
I still love the Meteor framework, even if it's not as popular these days. Auth "just works", The Mongo<->Server<->Client dataflow is super easy, and there's lots of tools to quickly and easily deploy it.

Now that React is supported, it's even easier for throwing together web apps.

> Quickly? Firebase + React.

Came here to recommend this myself.

I built an SPA with React + Firebase (auth, db, hosting, and all) to help my wife and I track our kids allowance and spending in just over a day: https://parentbank.actridge.com/ (did I mention Firebase hosting allows HTTPS on custom domains?)

It's an awesome combo that is seriously under-utilized.

The last couple prototypes I put up for work were using Flask and Vue on Heroku. I've been really happy with both how quickly they went up, but also how understandable everything is even a year later (they are only used internally).

The piece I wouldn't mind cutting out is heroku. If you do end up going the docker route, docker-machine is nice for being able to quickly put things up, "push" updates to digital ocean:

https://docs.docker.com/machine/examples/ocean/

I use Elixir/Phoenix mainly because I think it is fun and think that side projects should be fun. If it has the potential to become something more, I believe that it is a great production language for a company and would stake my business on it. Usually deploy to Heroku free tier for my up and fast prototypes.

Frontend will either be React or plain ol' JS depending on how complex the idea is.

Coming from nodejs, phoenix is incredible. Out of the box, phoenix just uses nodejs to generate all your frontend assets, and channels are incredibly easy to use. I'm still learning about how elixir works under the covers, but so far I'm really impressed.
How much learning curve if One doesn't know Erlang to get speed up in phoenix?
You don't really need to know Erlang.

Elixir is like if Erlang and Ruby had a child. It's a functional languages, so I guess there's a bit of a curve there. Plus you get stuff like macros, which are incredible, but I thought was some kind of voodoo magic the first time I encountered them.

There's a pretty decent tutorial on the elixir site, and the phoenix site if you want to learn.

As for the learning curve, I didn't struggle with it for very long at all, but your results may vary.

https://elixir-lang.org/getting-started/introduction.html

https://hexdocs.pm/phoenix/overview.html

These are two separate things: Erlang and Elixir are one, Phoenix is another.

In general, you don't need to know any Erlang to start working with Elixir. In time, as you advance your knowledge and start looking at more advanced features, you'll need the ability to read Erlang at some point, but that's actually pretty trivial: Erlang syntax is one of the simplest/smallest out there. It's much better in this case than it's with Clojure and Java.

The functional nature of Elixir may be a little weird, but, if you're worried about this, it's not taken to the extreme like in Haskell. At the end of the day, you do have a process dictionary (don't use it), and normal IO. It's true for both Erlang and Elixir, but Elixir adds some improvements on top of that: in Elixir, you can re-bind a variable (Erlang has single assignment only), you get the familiar syntax for accessing elements of collections (`coll[:keyname]`), the `if` is "fixed" to be normal if-then-else (the usual Erlang construct is dubbed `cond` in Elixir) and so on. It's FP but in the spirit of OCaml rather than Haskell: pragmatic and striving to be convenient without pulling the users' minds through a monad.

Now, Phoenix is another thing altogether. As far as frameworks go, Phoenix is very well designed, with a couple of orthogonal concepts being composed into a highly functional whole. To be honest, I didn't use Phoenix yet, personally - I did some code review for colleagues, but my own projects are written with Plug for now. Plug is a library which is comparable to WSGI spec in Python plus some additional utils, like in Werkzeug. Phoenix is built on top of Plug, so I figured learning it first is not a bad idea.

Turns out you can get by with Plug (and eventually some "plugs" packages from other people) for quite a while; the experience is like with Flask or Sinatra. You have to know what you want, exactly, but if you do, it's trivial to build a basic framework out of the available plugs. It's actually a strong selling point of the whole tech: as I mentioned, Plug is as much a library as a specification (with the same motivation as WSGI) and it's great for interoperability of components. The whole stack is composable and extensible at the same time, which is not that easy to pull off as far as framework designs go.

Documentation is decent, although its searchability is less so, I had a good time with devdocs.io for the core language and with hexdocs for plugs. It's definitely grokkable, and I'd say worth a try.

The biggest things you'd need to know is that Erlang does exist under the covers and you'll start spotting where it peaks through.

Once deployed, the best material on running beam apps is for Erlang, as well as ops tools like recon, and so you'll start learning and using it more then.