@hkdigital/lib-core
v0.5.98
Published
Core library that we use to power up our SvelteKit projects
Maintainers
Readme
HKdigital's lib-core
Core library that we use to power up our SvelteKit projects
This is a library for SvelteKit projects. It contains common code, base components and documentation that help you with setting up a new project.
Table of Contents
- Using the library
- Documentation
- Building the library
- Running the showcase app
- Developing
- Publishing
- Contribute
Using the library
Install
For projects/applications:
pnpm add @hkdigital/lib-coreFor other libraries:
pnpm add -D --save-peer @hkdigital/lib-corePeer Dependencies
For projects/applications, install peer dependencies:
# Core framework and utilities
pnpm add @sveltejs/kit svelte svelte-preprocess runed valibot
# UI framework and components
pnpm add @skeletonlabs/skeleton
# UI icons
pnpm add @steeze-ui/heroicons
# CSS processing (Tailwind and PostCSS)
pnpm add tailwindcss @tailwindcss/postcss postcss autoprefixer
# Logging
pnpm add pino pino-pretty
# JWT authentication (if using auth features)
pnpm add jsonwebtoken
# Linting
pnpm add @eslint/js eslint-plugin-import
# Image processing
pnpm add -D vite-imagetoolsFor other libraries, install as dev dependencies and declare as peer dependencies:
# Install as dev dependencies and peer dependencies
pnpm add -D --save-peer @sveltejs/kit svelte svelte-preprocess runed valibot @skeletonlabs/skeleton @steeze-ui/heroicons tailwindcss @tailwindcss/postcss postcss autoprefixer pino pino-pretty jsonwebtoken @eslint/js eslint-plugin-import vite-imagetoolsDesign System & Configuration
This library includes a complete design system with Tailwind CSS integration. Basic setup requires:
Tailwind config - Include library files in content scanning:
// tailwind.config.js import { generateTailwindThemeExtensions, designTokens, customUtilitiesPlugin } from '@hkdigital/lib-core/design/index.js'; const themeExtensions = generateTailwindThemeExtensions(designTokens); /** @type {import('tailwindcss').Config} */ export default { // Include @hkdigital libraries in content so Tailwind processes // their design system classes and components for proper styling content: [ './node_modules/@hkdigital/**/*.{html,js,svelte}', './src/**/*.{html,js,svelte}' ], theme: { // Extend Tailwind's default theme using the design system tokens extend: themeExtensions }, plugins: [ // Generate custom utility classes like 'type-heading-h2' customUtilitiesPlugin ] };Design tokens - Apply CSS variables in your layout:
<!-- src/routes/+layout.svelte --> <script> import { designTokens, designTokensToRootCssVars } from '@hkdigital/lib-core/design/index.js'; </script> <svelte:head> {@html designTokensToRootCssVars(designTokens)} </svelte:head> {@render children()}Vite configuration - Use the provided config generator:
// vite.config.js import { defineConfig } from 'vitest/config'; import { generateViteConfig } from '@hkdigital/lib-core/config/vite.js'; export default defineConfig( await generateViteConfig({ enableImagetools: true, enableVitest: true }) );Svelte configuration - Configure preprocessing and useful path aliases:
// svelte.config.js import { sveltePreprocess } from 'svelte-preprocess'; import adapter from '@sveltejs/adapter-auto'; /** @type {import('@sveltejs/kit').Config} */ const config = { // Enable preprocessing for external CSS files in Svelte components preprocess: sveltePreprocess({}), kit: { adapter: adapter(), alias: { $src: 'src', $examples: 'src/routes/examples' } } }; export default config;Image import type definitions - Add imagetools type support to
app.d.ts:// src/app.d.ts import '@hkdigital/lib-core/config/imagetools.d.ts'; // See https://svelte.dev/docs/kit/types#app.d.ts // for information about these interfaces declare global { namespace App { // interface Error {} // interface Locals {} // interface PageData {} // interface PageState {} // interface Platform {} } } export {};What this enables:
- Type definitions for image imports with query parameters (e.g.,
hero.jpg?preset=photo) - IntelliSense and autocompletion for imagetools directives in your editor
- Prevents TypeScript errors when importing processed images
- Works for both TypeScript and JavaScript projects (VS Code uses TypeScript for JS intellisense)
Available presets:
default- AVIF format, 90% qualityphoto- JPG format, 95% quality, returns metadatarender- JPG format, 95% quality, returns metadatagradient- JPG format, 95% quality, returns metadatadrawing- AVIF format, 90% quality, returns metadatasavedata- AVIF format, 85% quality, returns metadatablur- AVIF format, 50% quality with blur effect, returns metadata
Usage examples:
// Basic usage import heroImage from '$lib/assets/hero.jpg?preset=photo'; // Responsive images import heroResponsive from '$lib/assets/hero.jpg?preset=photo&responsive';- Type definitions for image imports with query parameters (e.g.,
Meta setup (optional) - SEO, PWA, and favicons:
The library includes templates for PWA configuration, SEO metadata, favicon generation, manifest.json, sitemap.xml, and robots.txt.
Quick setup:
# Copy template files to your project cp -r node_modules/@hkdigital/lib-core/meta/templates/lib/* src/lib/ cp -r node_modules/@hkdigital/lib-core/meta/templates/routes/* src/routes/Then customize
$lib/meta/config.jsand replace placeholder images in$lib/meta/with your own.For complete setup instructions and documentation, see:
Logging System
The library includes a comprehensive logging system that provides:
- Server-side: Structured JSON logging with pino and beautiful terminal formatting via pino-pretty
- Client-side: Enhanced console logging with structured data display in browser inspector
- Consistent API: Same logging interface for both server and client environments
- Tree-shaking optimized: Separate entry points for client and server code ensure optimal bundle sizes
Documentation
Comprehensive documentation organized by topic.
Getting Started
Start here if you're setting up a new project or library:
- New project setup - Complete guide for setting up a SvelteKit application with lib-core
- New library setup - Complete guide for setting up a SvelteKit library with lib-core
Architecture Guides
Learn how the different systems work together:
- Services & logging architecture
- How service management and logging integrate with SvelteKit
- Service patterns - Best practices and design patterns for implementing services
- Service plugins - ConfigPlugin and custom plugin development
API Reference
Detailed API documentation for each module:
- Logging - Server and client logging API, log levels, and formatters
- Services - ServiceBase and ServiceManager API reference
- Design system - Design tokens, theming, and UI utilities
- Vite configuration - Build configuration and optimization
Configuration
Reference documentation for configuration files:
- Root config files - Guide to vite.config.js, tailwind.config.js, and other root configs
Update
Make sure your project has a script called upgrade:hk to upgrade all packages
in the '@hkdigital' namespace.
pnpm upgrade:hkAvailable scripts
pnpm run dev # Start development server
pnpm run build # Build the library
pnpm run check # Type checking and validation
pnpm run test # Run unit tests
pnpm run upgrade:hk # Update all @hkdigital/... packages
pnpm run upgrade:all # Update all packages
pnpm run publish:npm # Version bump and publish to npmImport Validation
The library includes a validation script to enforce consistent import
patterns across both your project files and external @hkdigital/*
package imports.
Add to your project's package.json:
{
"scripts": {
"lint:imports": "node node_modules/@hkdigital/lib-core/scripts/validate-imports.mjs"
}
}Run validation:
# Using npm script (recommended)
pnpm run lint:imports
# Or directly
node node_modules/@hkdigital/lib-core/scripts/validate-imports.mjsAlias support:
The validator automatically reads path aliases from your
svelte.config.js and applies the same barrel export validation rules
to alias imports. This ensures consistent import patterns across:
- Internal
$lib/imports - External
@hkdigital/*package imports
Validation rules (enforced for src/lib/ files only):
- Alias optimization - Use
$libinstead of$src/lib(built-in SvelteKit alias) - Cross-domain imports - Use
$lib/instead of../../../ - Prefer barrel exports - Use higher-level export files when
available (applies to
$lib/, aliases, and@hkdigital/*packages) - Parent index.js imports - Use
$lib/or import specific files - Non-standard extensions - Include full extension (e.g.,
.svelte.js) - Directory imports - Write explicitly or create barrel export file
- File existence - All import paths must resolve to existing files
Barrel export preference:
The validator suggests using the highest-level barrel export file that exports your target. This encourages shorter imports that can be combined:
// Optimize built-in aliases:
import { MyComponent } from '$src/lib/ui/components.js';
// → Use: import { MyComponent } from '$lib/ui/components.js';
// Internal imports - instead of deep imports:
import ProfileBlocks from '$lib/ui/components/profile-blocks/ProfileBlocks.svelte';
import Button from '$lib/ui/primitives/buttons/Button.svelte';
// Use barrel exports:
import { ProfileBlocks } from '$lib/ui/components.js';
import { Button } from '$lib/ui/primitives.js';
// External imports - instead of deep imports:
import { TextButton } from '@hkdigital/lib-core/ui/primitives/buttons/index.js';
import { TextInput } from '@hkdigital/lib-core/ui/primitives/inputs/index.js';
// Use barrel exports:
import { TextButton, TextInput } from '@hkdigital/lib-core/ui/primitives.js';The validator checks from highest to lowest level ($lib/ui.js →
$lib/ui/components.js → $lib/ui/components/profile-blocks.js) and
suggests the highest-level file that exports your target. The same
logic applies to project aliases and external @hkdigital/* packages.
Routes are exempt from strict rules:
Files in src/routes/ can use relative imports freely, including parent
navigation and index.js imports. Since SvelteKit doesn't provide a
$routes alias, relative imports are the standard pattern for route
files.
Example output:
Validating import paths...
Found project aliases:
$src → src
$examples → src/routes/examples
src/lib/ui/panels/Panel.svelte:3
from '$src/lib/ui/components.js'
=> from '$lib/ui/components.js' (use built-in $lib alias)
src/lib/ui/panels/Panel.svelte:6
from '../../../components/profile-blocks/ProfileBlocks.svelte'
=> from '$lib/ui/components.js' (use barrel export)
src/lib/ui/pages/Profile.svelte:8
from '$lib/ui/components/profile-blocks/ProfileBlocks.svelte'
=> from '$lib/ui/components.js' (use barrel export for shorter imports)
src/lib/forms/LoginForm.svelte:6
from '@hkdigital/lib-core/ui/primitives/buttons/index.js'
=> from '@hkdigital/lib-core/ui/primitives.js' (use barrel export)
src/routes/explorer/[...path]/+page.svelte:4
from '../components/index.js'
✅ Allowed in routesWhat gets checked for barrel export suggestions:
The validator only suggests barrel exports (for $lib/ and external
@hkdigital/* packages) for:
- Explicit
index.jsimports - Component files (
.svelte) - Class files (capitalized
.jsfiles)
Intentional imports like helpers.js, config.js, or other lowercase
utility files are assumed to be the public API and won't be flagged.
Import Patterns and Export Structure
Public exports use domain-specific files matching folder names:
// Standard pattern: folder → matching .js export file
import { httpGet, httpPost } from '@hkdigital/lib-core/network/http.js';
import { CacheManager } from '@hkdigital/lib-core/network/cache.js';
import { LCHAR } from '@hkdigital/lib-core/constants/regexp.js';
import { Button } from '@hkdigital/lib-core/ui/primitives.js';Pattern:
- Folder
$lib/network/http/→ Export file$lib/network/http.js - Folder
$lib/network/cache/→ Export file$lib/network/cache.js - Folder
$lib/constants/regexp/→ Export file$lib/constants/regexp.js
Rare exception - index.js for aggregated APIs:
// Only used for large subsystems with public-facing aggregated APIs
import { designTokens } from '@hkdigital/lib-core/design/index.js';TypeDefs for JSDoc:
/**
* @param {import('@hkdigital/lib-core/network/typedef.js').HttpGetOptions}
* options
*/
function fetchData(options) {
// ...
}CSS Architecture (app.css)
CRITICAL: Your src/app.css must include the complete design system
architecture. Incomplete imports will cause build failures.
Required structure:
/* src/app.css */
/* 1. CSS Layers - Controls style precedence */
@layer theme, base, utilities, components;
/* 2. Tailwind CSS Core */
@import 'tailwindcss';
/* 3. HKdigital Design System Theme (ALL required for colors to work) */
@import '../node_modules/@hkdigital/lib-core/dist/design/themes/hkdev/theme.css' layer(theme);
@import '../node_modules/@hkdigital/lib-core/dist/design/themes/hkdev/globals.css';
@import '../node_modules/@hkdigital/lib-core/dist/design/themes/hkdev/components.css' layer(components);
@import '../node_modules/@hkdigital/lib-core/dist/design/themes/hkdev/responsive.css';
/* 4. Skeleton UI Framework */
@import '@skeletonlabs/skeleton' source('../node_modules/@skeletonlabs/skeleton-svelte/dist');
@import '@skeletonlabs/skeleton/optional/presets' source('../node_modules/@skeletonlabs/skeleton-svelte/dist');
/* 5. Tailwind Configuration Reference */
@config "../tailwind.config.js";
/* 6. Optional: Additional utilities */
/*@import '../node_modules/@hkdigital/lib-core/dist/css/utilities.css';*/Why all theme files are required:
- Missing any theme file will cause "Cannot apply unknown utility class" errors
- Classes like
bg-surface-100,text-primary-500won't work without complete theme - All four theme files (theme.css, globals.css, components.css, responsive.css) are needed
See src/lib/design/README.md for complete CSS architecture documentation.
Critical: data-theme Attribute
IMPORTANT: Add data-theme="hkdev" to your <body> element in
src/app.html. Without this, theme colors will not work correctly.
<!-- src/app.html -->
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
%sveltekit.head%
</head>
<body data-theme="hkdev" data-sveltekit-preload-data="hover">
<div>%sveltekit.body%</div>
</body>
</html>Why this is required:
- Theme CSS custom properties are scoped to
[data-theme='hkdev'] - Without this attribute, colors fall back to browser defaults
- Symptom: Colors like
bg-primary-500show grey instead of magenta - Solution: Add
data-theme="hkdev"to<body>element
Building the library
To build your library:
pnpm run packageRunning the showcase app
To use the showcase app that illustrates the code in this lib
pnpm run devYou can preview the production build with pnpm run preview.
To deploy your app, you may need to install an adapter for your target environment.
Developing
To develop this library, clone the repository and install the dependencies, then start the development server of the test runners. Checkout the package.json file for more details.
Everything inside src/lib is part of the library, everything inside src/routes is the showcase app of this library.
Publishing
The name of this library is @hkdigital/lib-core and it is published on NPM. You need NPM credentials to publish in the scope @hkdigital.
# Manually
npm login
npm version patch
npm publish --access public# Run `npm version patch && npm publish --access public && git push`
# as specified in package.json
pnpm run publish:npmTroubleshooting
Running scripts from package.json in Windows
The CMD terminal in Windows is quite limited. Use the PowerShell instead of some scripts from package.json do not run correctly.
Contribute
If your wish to contribute to this library, please contact us HKdigital. Alternatively, the license permits you to fork the library and publish under an alternative name. Don't forget to change the package name in package.json if you do so.
