Svelte CRUD tutorial with Node.js

Svelte CRUD tutorial with Node.js

Svelte is a modern JavaScript framework for building fast, reactive user interfaces. Unlike traditional frameworks like React or Vue, Svelte shifts much of the work to compile time.

This means that Svelte applications don’t rely on a virtual DOM but instead compile components into highly efficient imperative code that directly updates the DOM. This approach leads to smaller bundle sizes and faster runtime performance.

Why Use Svelte?

  • Zero Virtual DOM: Svelte updates the DOM directly, leading to more efficient rendering.
  • Reactive Declarations: Automatically update your UI when your state changes, making reactive programming simple.
  • Component-Based Architecture: Svelte components encapsulate HTML, CSS, and JavaScript, promoting reusability and maintainability.
  • Small Bundle Size: Since Svelte compiles to vanilla JavaScript, it results in smaller and faster bundles.

Setting Up a Svelte Project

To get started with Svelte, you need to have Node.js and npm installed. Here's how to set up a new Svelte project:

npx degit sveltejs/template svelte-crud-app
cd svelte-crud-app
npm install
npm run dev

This sets up a new Svelte project and runs a development server. You can now access your app at http://localhost:5000.

Creating a REST API Backend

Before diving into the Svelte CRUD operations, you need a REST API to interact with. You can use any backend technology, but for simplicity, here’s an example using Node.js and Express:

npm init -y
npm install express cors body-parser

Create a server.js file with the following content:

const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');

const app = express();
app.use(cors());
app.use(bodyParser.json());

let items = [
  { id: 1, name: 'Item 1' },
  { id: 2, name: 'Item 2' },
];

app.get('/items', (req, res) => res.json(items));

app.post('/items', (req, res) => {
  const newItem = { id: Date.now(), ...req.body };
  items.push(newItem);
  res.json(newItem);
});

app.put('/items/:id', (req, res) => {
  const { id } = req.params;
  const index = items.findIndex((item) => item.id == id);
  if (index !== -1) {
    items[index] = { ...items[index], ...req.body };
    res.json(items[index]);
  } else {
    res.status(404).json({ message: 'Item not found' });
  }
});

app.delete('/items/:id', (req, res) => {
  items = items.filter((item) => item.id != req.params.id);
  res.json({ message: 'Item deleted' });
});

app.listen(3000, () => console.log('Server running on http://localhost:3000'));

This code creates a simple REST API with CRUD operations for a list of items.

Integrating Svelte with the REST API

In your Svelte project, let's create a simple CRUD interface to interact with this API.

Fetch Items from the API

Create a new Svelte component Items.svelte:

<script>
  import { onMount } from 'svelte';

  let items = [];

  onMount(async () => {
    const response = await fetch('http://localhost:3000/items');
    items = await response.json();
  });
</script>

<h1>Items</h1>
<ul>
  {#each items as item}
    <li>{item.name}</li>
  {/each}
</ul>

Add a New Item

Extend the Items.svelte component to include a form for adding new items:

<script>
  import { onMount } from 'svelte';

  let items = [];
  let newItemName = '';

  onMount(async () => {
    const response = await fetch('http://localhost:3000/items');
    items = await response.json();
  });

  async function addItem() {
    const response = await fetch('http://localhost:3000/items', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ name: newItemName }),
    });
    const item = await response.json();
    items = [...items, item];
    newItemName = '';
  }
</script>

<h1>Items</h1>
<ul>
  {#each items as item}
    <li>{item.name}</li>
  {/each}
</ul>

<input bind:value={newItemName} placeholder="New Item" />
<button on:click={addItem}>Add Item</button>

Update an Item

Modify the component to allow updating items:

<script>
  import { onMount } from 'svelte';

  let items = [];
  let newItemName = '';
  let editingItem = null;

  onMount(async () => {
    const response = await fetch('http://localhost:3000/items');
    items = await response.json();
  });

  async function addItem() {
    if (editingItem) {
      const response = await fetch(`http://localhost:3000/items/${editingItem.id}`, {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ name: newItemName }),
      });
      const updatedItem = await response.json();
      items = items.map((item) => (item.id === updatedItem.id ? updatedItem : item));
      editingItem = null;
    } else {
      const response = await fetch('http://localhost:3000/items', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ name: newItemName }),
      });
      const item = await response.json();
      items = [...items, item];
    }
    newItemName = '';
  }

  function editItem(item) {
    editingItem = item;
    newItemName = item.name;
  }
</script>

<h1>Items</h1>
<ul>
  {#each items as item}
    <li>
      {item.name}
      <button on:click={() => editItem(item)}>Edit</button>
    </li>
  {/each}
</ul>

<input bind:value={newItemName} placeholder="New Item" />
<button on:click={addItem}>{editingItem ? 'Update' : 'Add'} Item</button>

Delete an Item

Add functionality to delete items:

<script>
  import { onMount } from 'svelte';

  let items = [];
  let newItemName = '';
  let editingItem = null;

  onMount(async () => {
    const response = await fetch('http://localhost:3000/items');
    items = await response.json();
  });

  async function addItem() {
    if (editingItem) {
      const response = await fetch(`http://localhost:3000/items/${editingItem.id}`, {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ name: newItemName }),
      });
      const updatedItem = await response.json();
      items = items.map((item) => (item.id === updatedItem.id ? updatedItem : item));
      editingItem = null;
    } else {
      const response = await fetch('http://localhost:3000/items', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ name: newItemName }),
      });
      const item = await response.json();
      items = [...items, item];
    }
    newItemName = '';
  }

  function editItem(item) {
    editingItem = item;
    newItemName = item.name;
  }

  async function deleteItem(id) {
    await fetch(`http://localhost:3000/items/${id}`, {
      method: 'DELETE',
    });
    items = items.filter((item) => item.id !== id);
  }
</script>

<h1>Items</h1>
<ul>
  {#each items as item}
    <li>
      {item.name}
      <button on:click={() => editItem(item)}>Edit</button>
      <button on:click={() => deleteItem(item.id)}>Delete</button>
    </li>
  {/each}
</ul>

<input bind:value={newItemName} placeholder="New Item" />
<button on:click={addItem}>{editingItem ? 'Update' : 'Add'} Item</button>

Conclusion

This tutorial provides a simple example of integrating Svelte with a REST API to perform CRUD operations.

Svelte’s reactive nature makes it easy to handle state and DOM updates, while its component-based architecture promotes code reusability. You can expand this tutorial by adding features like authentication, routing, or connecting to a database in your REST API.








Open-source Apps

9,500+

Medical Apps

500+

Lists

450+

Dev. Resources

900+