User Management

SvelteForge Admin provides full CRUD operations for user management, powered by SvelteKit form actions and Svelte 5 reactivity. Users are stored in SQLite via Drizzle ORM with Argon2id password hashing, role-based access control, and comprehensive server-side validation.


User Table

The user table loads all users server-side through the load function in users/+page.server.ts. Data is fetched from the Drizzle ORM users table, ordered by creation date (newest first).

Features

  • Sortable columns — Click column headers to sort by name, email, username, role, or creation date.
  • Search filtering — Real-time filtering across name, email, and username using $state and $derived runes from Svelte 5.
  • Pagination — The data-table-pagination component provides page navigation with configurable page sizes.
  • Page size selector — Choose between 10, 25, or 50 rows per page. The selection persists across navigation.
  • CSV and JSON export — Export visible or all user data using utility functions from #lib/utils/export.ts.

Server-Side Data Loading

// users/+page.server.ts — load function
export const load: PageServerLoad = async () => {
  const allUsers = db.select().from(users).orderBy(desc(users.createdAt)).all();
  return { users: allUsers };
};

Creating Users

New users are created through the user-form-dialog.svelte component, which renders a form inside a dialog. Only administrators can create users.

Form Fields

FieldRequirements
NameRequired, displayed in the UI and exports
EmailRequired, must be unique across all users
Username3-31 characters, lowercase alphanumeric only
PasswordRequired, hashed with Argon2id before storage
RoleSelect from Admin, Editor, or Viewer

Server-Side Validation

The create form action in users/+page.server.ts performs the following checks before inserting a new user:

  • Username format validation (3-31 lowercase alphanumeric characters)
  • Email uniqueness check against existing users
  • Password requirements enforcement
  • Argon2id hashing of the password before database insertion

The form uses SvelteKit's use:enhance for progressive enhancement, keeping the page interactive while the server processes the request.


Editing Users

The same user-form-dialog.svelte component handles editing when opened in edit mode. The dialog pre-populates all fields with the selected user's current data.

  • All fields are editable, including role assignment.
  • The update form action validates changes server-side with the same rules as creation.
  • Last-admin protection — The server prevents demoting the last remaining admin to a lower role, ensuring at least one admin always exists.

Deleting Users

User deletion is handled by the delete-confirm-dialog.svelte component, which requires explicit confirmation before proceeding.

Safety Checks

  • Self-deletion prevention — Users cannot delete their own account.
  • Last-admin protection — The system blocks deletion if it would remove the last administrator.

Bulk Delete

Select multiple users via checkboxes and delete them in a single action. The bulk delete operation:

  • Automatically filters out the current user from the selection.
  • Blocks the operation if deleting the selected users would remove all remaining administrators.
  • Uses the bulkDelete form action, which processes all deletions in a single database transaction.

Role-Based Access Control (RBAC)

SvelteForge Admin implements a three-tier role system. The first user to register is automatically assigned the Admin role.

Role Capabilities

CapabilityAdminEditorViewer
View dashboardYesYesYes
View users listYesYesYes
Create usersYesNoNo
Edit usersYesNoNo
Delete usersYesNoNo
Manage rolesYesNoNo
Manage contentYesYesNo
View analyticsYesYesNo
Manage settingsYesNoNo

Role Changes

Administrators can change a user's role via a dedicated role change dialog. A confirmation step is required, and the system enforces that at least one admin must remain at all times. Permission checks run inside the SvelteKit form actions to prevent unauthorized role modifications.


Export

User data can be exported in two formats using shared utility functions from #lib/utils/export.ts:

  • CSV export — Properly escapes values containing commas, double quotes, and newlines. Fields are wrapped in quotes when necessary, following RFC 4180.
  • JSON export — Pretty-printed with 2-space indentation for readability.

Both formats trigger a browser download with an appropriately named file.


Svelte 5 Patterns Used

The user management module demonstrates several Svelte 5 patterns throughout:

  • $state — Reactive state for search query, current page number, and page size.
  • $derived — Computed values for filtered user lists and paginated slices, automatically updating when dependencies change.
  • use:enhance — SvelteKit's progressive enhancement directive on all forms, enabling non-blocking submissions without full page reloads.
  • {@render} — Snippet-based rendering for table cell content, enabling reusable column templates.
// Svelte 5 reactive patterns in the users page
let search = $state('');
let currentPage = $state(1);
let pageSize = $state(10);

let filteredUsers = $derived(
  users.filter((u) =>
    u.name.toLowerCase().includes(search.toLowerCase()) ||
    u.email.toLowerCase().includes(search.toLowerCase())
  )
);

let paginatedUsers = $derived(
  filteredUsers.slice((currentPage - 1) * pageSize, currentPage * pageSize)
);

Need More Than User Management?

DashboardPack premium admin templates include full CRUD modules for Orders, Products, Customers, Invoices, and more — all built with Svelte 5 and SvelteKit, ready for production.

Explore DashboardPack Premium