Giter Club home page Giter Club logo

nickjs's Introduction

Nick.js

Nick.js is a lightweight web framework (glorified starter project, really) built with Bun, ElysiaJS, Kysely, React, and Tailwind. It is designed to be type-safe, performant, easy to use, and flexible.

It is is very beta software, mostly intended for personal use. Exercise caution if using for any serious project.

Installation

To create a new Nick.js project:

bun create nickjs

Be sure to verify that you get the latest version of Nick.js (i.e. the version in package.json). There is currently a Bun bug that results in bunx using stale versions of packages.

SSR

Nick.js supports basic server-side rendering + hydration. Each incoming page request is routed to a controller (i.e. an async function), which is responsible for retrieving any data the page needs, then returning a React element. The server's initial response will include only the rendered HTML plus two script tags - one to load React (typically already in the browser cache) and one to load javascript that responsible for hydrating the current page.

There is one piece of magic required to make SSR and hydration work: Each React element returned by a controller must passed through @ssr/app/clientRoot. At build time, a custom Bun plugin will replace this function call with code that renders the given component to an html string and appends scripts to hydrate the page.

While not necessary, it's often convenient for controllers to use the @server/util/pageController and @server/util/controller/decoratePageProps helpers to add type information and pass common props (e.g. currentUser) to the page component.

const userController = pageController<UserSchema>(async (props) => {
  const user = await client
    .selectFrom('User')
    .selectAll()
    .where('id', '=', props.params.id)
    .executeTakeFirstOrThrow();

  return clientRoot(UserPage, decoratePageProps(props, { user }));
});

export { userController };
function UserPage({ currentUser, user }: PageProps<{ user: User }>) {
  return (
    <Page title={user.name}>
      <div className="flex flex-row items-center gap-2">
        <Avatar url={user.avatarUrl} />
        <span className="font-bold">{user.name}</span>
        {user.id === currentUser?.id && (
          <a href={`/users/${user.id}/edit`}>Edit</a>
        )}
      </div>
    </Page>
  );
}

export { UserPage };

Code Organization

Server code lives in src/server, aliased as @server.
Client code lives in src/client, aliased as @client.
Shared code (e.g. types, runtime-agnostic utility functions) lives in src/shared, aliased as @shared.

ESlint rules are configured to prevent client code from importing any Bun/Node packages or code outside of the @client and @shared directories. This helps to ensure that server-side code is never referenced in a client bundle.

Server

The server is configured in @server/server.tsx. By default, Nick.js enables ElysiaJS plugins for authentication, Tailwind styles, error handling, compression, rate limiting, securing http response headers, serving static files/folders, and adding request ids. It's recommended to use ElysiaJS schemas to type and validate request inputs (e.g. path params, search params, body). Follow the patterns in @shared/type/controller to define schema validations for ElysiaJS and derive types that can be passed into ControllerProps.

Database

Nick.js uses Kysely to interact with a PlanetScale-hosted MySQL database. Migrations can be found in @server/database/migration. By default, projects come with User, Oauth, and Session tables for basic authentication. New migrations can be run with bun run migrate:to-latest, which will have the effect of auto-generating + saving database types to @shared/type/db/generated.ts. When executing queries, use the client instance from @server/database/client.

nickjs's People

Contributors

nickcherry avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.