Cloudless

A Pain Free Way to Build Cloud Apps

Posted by Ryland Goldstein on May 3, 2019

TL;DR Video Overview

Every so often, an idea for a new web app pops into my head. Due to being an excitable engineer by trade, the idea immediately cascades into “web-scale” architecture design accompanied by a months long roadmap. But when it comes time to finally sit down and get to work, reality strikes and I remember the cascade of configuration, boilerplate nonsense and general frustration required to get a backend off the ground. I wanted something that would allow me to spend 100% of my time working on core value, and 0% of my time configuring or managing a tool.

The result is Cloudless (name subject to change), a single service and webpack plugin that seamlessly integrates into CRA (Create React App) and allows me to create my backend resources (compute, data, certificates, etc), with a simple JavaScript annotation such as:

// @backend
export async function createItem(todoText) {
  return CloudStorage.update(todoKey, (todos) =>
    todos.concat({ id: uuidv4(), text: todoText }), []);
}

At build time, the plugin plucks out the annotated functions and continuously deploys them to the cloud. No longer do I need to switch contexts and wait minutes for my backend changes to propagate - “it just works”. But code is just part of the equation, what about data?

return CloudStorage.update(todoKey, (todos) =>
    todos.concat({ id: uuidv4(), text: todoText }), []);

Cloudless provides CloudStorage, an automatically provisioned, fully managed datastore that is modeled after API’s that make sense to frontend devs (yes, localStorage, I’m looking at you). CloudStorage addresses all of your data needs, whether that be caching, user information, scratch memory, the list goes on. While it might be clear to see how CloudStorage supports traditional data requirements, what about something more involved, such as automatic updates between clients?

TodoBackend.js

// @backend
export async function pollOnTodos(fromVersion) {
  return await CloudStorage.poll(todoKey, fromVersion);
}

Todo.js

const Todo = () => {
  const state = useSubscription('todos', initialValue, getInitialTodos, pollOnTodos);
  // removed for brevity
}

With only two lines of code we are able to add support for live updates in our Todo application. Once again, there’s no gimmick, it’s just that easy. Not convinced? (see it in action in the below video)

I assume that by this point you’re as excited as I am, so you probably want to see what a full backend might look like. I’m not one to keep people waiting, so here is the Todo backend in its entirety.

TodoBackend.js

import { v4 as uuidv4 } from 'uuid';

const todoKey = 'todos';
const initialValue = [];

// @backend
export async function createItem(todoText) {
  return CloudStorage.update(todoKey, (todos) =>
    todos.concat({ id: uuidv4(), text: todoText }), initialValue);
}

// @backend
export async function deleteItem(todoID) {
  await CloudStorage.update(todoKey, (todos) =>
    todos.filter(({ id }) => id !== todoID), initialValue);
}

// @backend
export async function getTodos(todoID) {
  return CloudStorage.get(todoKey, initialValue);
}

// @backend
export async function pollOnTodos(fromVersion) {
  return await CloudStorage.poll(todoKey, fromVersion);
}

Worry not, there’s no lurking configuration files waiting to ruin your day, or complex CLI deployment options to turn your stomach. This is it.

If it still seems a bit “impossible”, here’s a video that should help with that.

Cloudless is an open source framework, backed by a powerful serverless platform that aims to eliminate all of the overhead traditionally associated with full stack development. It enables you to be in control of as much, or as little of how your web app runs as you please, so you can focus on what’s important without paying the price of performance or flexibility.

Cloudless is still a baby, so it’s not yet publicly available. But that doesn’t mean we aren’t looking for feedback. If you like what you saw, have questions, comments, concerns or anything else please comment below!

Our driving mission is to further the webdev community, so feedback is paramount.

ry@binaris.com