Nullstack é um web framework que torna programar divertido novamente.
Escreva o backend e o frontend de um recurso em um único componente isomórfico sem boilerplate ou glue code.
class WaifuCounter extends Nullstack {
  // roda no servidor
  static async getWaifus({ database }) {
    const sql = "SELECT COUNT(*) FROM WAIFUS";
    return database.query(sql);
  }
  // roda no cliente
  async countWaifus() {
    this.waifus = this.getWaifus()
  }
  // roda onde for melhor
  render() {
    return (
      <button onclick={this.countWaifus}>
        Count: {this.waifus}
      </button>
    );
  }
}

Na primeira visita, você terá HTML pronto para SEO e otimizado para a primeira renderização de sua rota em uma única solicitação usando funções locais com nenhuma dependência de JavaScript no pacote do cliente

Depois que o conteúdo é servido e a rede está ociosa, o JavaScript do Nullstack é carregado, o estado da aplicação é restaurado por meio de hidratação e torna-se uma aplicação de página única (SPA)

As funções de servidor subsequentes buscarão JSON de uma API de microsserviços gerada automaticamente, desserializarão a resposta, atualizarão o estado da aplicação e renderizarão a página sem nenhum código adicional
class WaifuCreator extends Nullstack {
  // extraído em um microsserviço
  static async insertWaifu({ database, name }) {
    const sql = "INSERT INTO waifus (name) VALUES (?)";
    return database.query(sql, name);
  }
  // invoca o microsserviço
  async create() {
    this.insertWaifu({ name: "Nulla-Chan" })
  }
  // renderiza no DOM
  render() {
    return (
      <button onclick={this.create}>
        Criar Waifu
      </button>
    );
  }
  
}
Você escreve recursos para produtos. O compilador extrai seu código de frontend e substitui todas as funções assíncronas estáticas por chamadas para microsserviços

class Vanilla extends Nullstack {
  // variáveis são apenas variáveis
  count = 0;
  // mutações refletem no dom
  increment() {
    this.count++
  }
  // 'this' é vinculado por padrão
  render() {
    return (
      <button onclick={this.increment}> 
        {this.count}
      </button>
    )
  }
}Seus componentes são apenas POJOs. Aproveite as vantagens do ecossistema existente enquanto escreve JavaScript como deve ser e veja o resultado refletido no dom.

class Modern extends Nullstack {
  // 'params' são injetados em cada função
  renderWaifu({ params }) {
    return (
      <p> Olá, eu sou a {params.name} </p>
    )
  }
  // as rotas podem ter segmentos dinâmicos
  render() {
    return (
      <>
        <Waifu route="/waifus/:name" />
        <a href="/waifus/Nulla">
          NullaChan
        </a>
      </>
    )
  }
}As rotas são atributos simples que você pode atribuir a qualquer tag, e os links são apenas tags 'a'. Você descobrirá que Nullstack é apenas uma versão moderna de sua stack atual.

class Batteries extends Nullstack {
  // variáveis podem ser vinculadas ao dom
  name = 'Nulla-Chan';
  isWaifu = true;
  
  render() {
    // preparando um evento em objeto
    const isWaifu = !this.isWaifu;
    // eventos são evitados por padrão
    return (
      <form>
        <input bind={this.name} />
        <button onclick={{isWaifu}}>
          Alternar Waifu
        </button>
      </form>
    )
  }
}A maioria das tarefas são muito repetitivas. Economize sua energia para os desafios reais usando os atalhos que criamos, como eventos em objeto e vínculos bidirecionais.
