DEV Community

Cover image for Bun
Agus Sudarmanto
Agus Sudarmanto

Posted on

Bun

Wait, what is Bun

Bun is a java script runtime that is designed to be fast and efficient. It is built on top of the JavaScriptCore engine and uses a number of optimizations, advantages of using the low-level language Zig to make it faster.

Install Bun and init

curl -fsSL https://bun.sh/install | bash
bun init
Enter fullscreen mode Exit fullscreen mode

Experiment with Elysia (Bun Framework)

Elysia is ergonomic Framework for Humans, TypeScript with End-to-End Type Safety, unified type system and outstanding developer experience. Supercharged by Bun.

Preparation:

  1. Install packages
  2. Configure knex
  3. Configure database
  4. Configure environment
  5. Create migration file and run it
  6. Create controller
  7. Run server
  8. Using docker

# 1. Install packages

bun add elysia knex dotenv pg
knex init
Enter fullscreen mode Exit fullscreen mode

# 2. Configure knex

// -- knexfile.js
require("dotenv").config();

export const development = {
  client: "pg",
  connection: process.env.DATABASE_URL,
  migrations: {
    directory: "./db/migrations",
  }
};
Enter fullscreen mode Exit fullscreen mode

# 3. Configure database

// -- db.js 
const knex = require("knex");
const knexFile = require("./knexfile.js");

const environment = process.env.NODE_ENV || "development";

export default knex(knexFile[environment]);
Enter fullscreen mode Exit fullscreen mode

# 4. Configure environment

// -- .env
DATABASE_URL = <YOUR_DATABASE_URI>
Enter fullscreen mode Exit fullscreen mode

# 5. Create migration file and run it

run knex migrate:make blog

/**
 * @param { import("knex").Knex } knex
 * @returns { Promise<void> }
 */
export function up (knex) {
  return knex.schema.createTable("blog", (table) => {
    table.increments("id").primary();
    table.string("title").notNullable();
    table.string("content").notNullable();
    table.string("author").notNullable();
    table.timestamp("created_at").defaultTo(knex.fn.now());
  });
}

/**
 * @param { import("knex").Knex } knex
 * @returns { Promise<void> }
 */
export function down (knex) {
  return knex.schema.dropTable("blog");
}
Enter fullscreen mode Exit fullscreen mode

After creating migration table, run knex migrate:latest

# 6. Create controller

// -- index.ts
const { Elysia } = require("elysia");
let db = require("./db");
db = db.default;
const app = new Elysia();

// -- New post
app.post("/posts/create-new-post", async (context) => {
  try {
    //Extract the title, content and author from the request body
    const { title, content, author } = context.body;

    //Insert the post into the database
    const post = await db("blog").insert({
      title,
      content,
      author,
    });

    //Send response to the client
    return new Response(JSON.stringify(post));
  } catch (error: any) {
    //Send error to the client
    return new Response(error.message, { status: 500 });
  }
});

// -- Get all posts
app.get("/posts", async (context) => {
  try {
    //Get all posts from the database
    const posts = await db.select("*").from("blog");

    //Send response to the client
    return new Response(JSON.stringify(posts));
  } catch (error: any) {
    //Send error to the client
    return new Response(error.message, { status: 500 });
  }
});

// -- Get post by ids
app.get("/posts/:id", async (context) => {
  //Extract the id from the request params
  const { id } = context.params;

  //Get the post from the database
  const post = await db("blog").where({ id });

  //If the post is not found, send a 404 response
  if (post.length === 0) {
    return new Response("Post not found", { status: 404 });
  }

  //Send response to the client
  return new Response(JSON.stringify(post));
});

// -- Update post
app.patch("/posts/:id/update-post", async (context) => {
  //Extract the id from the request params
  const { id } = context.params;

  //Extract the title and content from the request body
  const { title, content } = context.body;

  //Update the post in the database
  const post = await db("blog").where({ id }).update(
    {
      title,
      content,
    },
    ["id", "title", "content"]
  );

  //Send response to the client
  return new Response(JSON.stringify(post));
});

// -- Delete post
app.delete("/posts/:id/delete-post", async (context) => {
  //Extract the id from the request params
  const { id } = context.params;

  //Delete the post from the database
  const post = await db("blog").where({ id }).del();

  //Send response to the client
  return new Response(JSON.stringify(post));
});

app.listen(3000, () => {
  console.log("Server running on port 3000");
});
Enter fullscreen mode Exit fullscreen mode

# 7. Run server

Then run bun --watch index.ts

# 8. Using Docker

run touch Dockerfile

FROM oven/bun

WORKDIR /app

COPY package.json .
COPY bun.lockb .

RUN bun install

COPY . .

EXPOSE 3000

CMD ["bun", "index.ts"]
Enter fullscreen mode Exit fullscreen mode

Postgres on Neon - Get the Free Plan

No credit card required. The database you love, on a serverless platform designed to help you build faster.

Get Postgres on Neon

Top comments (0)

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up