# lincd-server

> HTTP server & utilities for LINCD applications, running on node.js.

Latest version **1.0.7** (published 2025-12-28) · ISC license · 0 weekly downloads

## Install

```sh
npm install lincd-server
pnpm add lincd-server
yarn add lincd-server
bun add lincd-server
```

## Health

**Score 55/100 (C)** — status: stable.

Positive: has types; esm support; no vulnerabilities.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 1.0.7 |
| Published | 2025-12-28 |
| First published | 2022-09-23 |
| Weekly downloads | 0 |
| License | ISC |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 38 |
| Unpacked size | 472.3 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | René Verheij |
| Maintainers | rene_reborn |
| Keywords | lincd, server, nodejs, express, linked data, interoperable, semantic web, web3 |

## Links

- npm: https://www.npmjs.com/package/lincd-server
- npm.io page: https://npm.io/package/lincd-server

## Dependencies (38)

- [n3](https://npm.io/package/n3.md) ^1.17.2
- [cors](https://npm.io/package/cors.md) ^2.8.5
- [cron](https://npm.io/package/cron.md) ^4.3.4
- [open](https://npm.io/package/open.md) ^8.4.0
- [chalk](https://npm.io/package/chalk.md) 4.1.2
- [lincd](https://npm.io/package/lincd.md) ^1.0
- [react](https://npm.io/package/react.md) ^18.2
- [sharp](https://npm.io/package/sharp.md) ^0.34.4
- [rimraf](https://npm.io/package/rimraf.md) ^5.0.5
- [adm-zip](https://npm.io/package/adm-zip.md) ^0.5.16
- [express](https://npm.io/package/express.md) ^4.18.3
- [webpack](https://npm.io/package/webpack.md) ^5.90.3
- [archiver](https://npm.io/package/archiver.md) ^7.0.1
- [is-object](https://npm.io/package/is-object.md) ^1.0.2
- [lincd-cli](https://npm.io/package/lincd-cli.md) ^1.2
- [node-hook](https://npm.io/package/node-hook.md) ^1.0.0
- [react-dom](https://npm.io/package/react-dom.md) ^18.2
- [lincd-sioc](https://npm.io/package/lincd-sioc.md) ~1.0
- [typescript](https://npm.io/package/typescript.md) ^5.7.3
- [body-parser](https://npm.io/package/body-parser.md) ^1.20.2
- [compression](https://npm.io/package/compression.md) ^1.7.4
- [autoprefixer](https://npm.io/package/autoprefixer.md) ^10.4.18
- [fetch-cookie](https://npm.io/package/fetch-cookie.md) ^3.1.0
- [lincd-jsonld](https://npm.io/package/lincd-jsonld.md) ~1.0
- [lincd-sparql](https://npm.io/package/lincd-sparql.md) ~1.0
- [tough-cookie](https://npm.io/package/tough-cookie.md) ^6.0.0
- [zip-a-folder](https://npm.io/package/zip-a-folder.md) ^3.1.8
- [lincd-modules](https://npm.io/package/lincd-modules.md) ~1.0
- [lincd-storage](https://npm.io/package/lincd-storage.md) ~1.0
- [node-addon-api](https://npm.io/package/node-addon-api.md) ^8.2.2
- [proper-lockfile](https://npm.io/package/proper-lockfile.md) ^4.1.2
- [react-router-dom](https://npm.io/package/react-router-dom.md) ^6.22.3
- [lincd-jsonld-store](https://npm.io/package/lincd-jsonld-store.md) ~1.0
- [lincd-server-utils](https://npm.io/package/lincd-server-utils.md) ~1.0
- [react-error-boundary](https://npm.io/package/react-error-boundary.md) ^4.0.13
- [webpack-dev-middleware](https://npm.io/package/webpack-dev-middleware.md) ^7.0.0
- [webpack-hot-middleware](https://npm.io/package/webpack-hot-middleware.md) ^2.26.1
- [tsconfig-to-dual-package](https://npm.io/package/tsconfig-to-dual-package.md) ^1.2.0

## Recent versions

- 1.0.7 (latest) — 2025-12-28
- 1.0.6 — 2025-12-02
- 1.0.5 — 2025-11-26
- 1.0.4 — 2025-11-26
- 1.0.3 — 2025-11-26
- 1.0.2 — 2025-05-08
- 1.0.1 — 2025-05-08
- 0.1.45 — 2024-08-10
- 1.0.0 — 2024-05-30
- 0.1.44 — 2023-11-17
- 0.1.42 — 2023-09-01
- 0.1.41 — 2023-09-01
- 0.1.40 — 2023-08-31
- 0.1.39 — 2023-08-04
- 0.1.38 — 2023-07-03
- … 38 more at https://npm.io/package/lincd-server/versions

## README

# LINCD Server

This package provides a `LincdServer` which can be used to instantiate a LINCD backend environment on node.js.

If you use `npx lincd-cli create-app [name]` it will already set everything up for you to use `LincdServer`.
To see how it's used, open `your-site/backend/server.js`.

If you require any additional features, feel free to make a request at the LINCD Discord server.
If you want to further adjust the functionality of LincdServer yourself, either extend it or clone this repo locally.

---

## Table of contents

- [Environment Variables](#environment-variables)
- [Calling methods on the backend](#calling-methods-on-the-backend)
  - [Shape providers](#shape-providers)
  - [Generic backend providers](#generic-backend-providers)
  - [Gotchas](#gotchas)
- [Shapes](#shapes)
  - [LocalFileStore](#localfilestore)
- [TODO](#todo)

---

## Environment Variables

```properties
# The port on which the server will listen
PORT=3000

# A descriptive URI for where the app's data can live
DATA_ROOT=https://app.my-site.com/data

# The site's URL - will also be used for LocalFileStore
SITE_ROOT=http://localhost:3000  # or https://app.my-site.com

# "development" or "production"
NODE_ENV=development
```

## Calling methods on the backend

When you use LincdServer, you can also implement backend methods that you can access from the frontend.

There is two ways to do this:

### Shape providers

With Shape providers you can connect shapes to a backend method.

Let's say for example you want to send an email to a specific person from the server.
You could do that from a Person shape like so:

```typescript
import { linkedShape } from '../package';
import { Shape } from 'lincd/lib/shapes/Shape';
import { Server } from 'lincd-server/lib/utils/Server';

@linkedShape
export class Person extends Shape {
  sendEmail(subject: string, message: string): Promise<boolean> {
    return Server.call(this, 'sendEmail', subject, message);
  }
}
```

Note that `Server.call()` first takes the instance of the shape, then the method name and than any number of arguments
to be passed on.

To implement the backend, create `src/shapes/PersonProvider.ts`:

```typescript
import Person from './Person';
import { ShapeProvider } from 'lincd-server-utils/lib/utils/ShapeProvider';

export class PersonProvider extends ShapeProvider {
  static shape = Person;

  static sendEmail(person: Person, subject: string, message: string): boolean {
    //send email to person
    //mail(person.mailbox,subject,message);
  }
}
```

Here, PersonProvider first of all registers itself as a provider of the `Person` shape with `static shape = Person`.

Then it implements the method (sendEmail()) as a a _static_ method, which receives an instance of the shape it is
connected to as its first argument.

To make sure the provider is _compiled_ but _not bundled_ you need to add it to `tsconfig`.

The recommended way to do that is with a providers index file `src/providers.ts`.
This file will re-export all providers of your package:

```typescript
//src/providers.ts
export * from './shapes/PersonProvider';
```

Finally, add `providers.ts` to your `src/tsconfig.json`:

```json5
//tsconfig.json
{
  //...
  files: ['./src/index.ts', './src/providers.ts'],
}
```

That's all that's required to connect your frontend shapes to backend code.

### Generic backend providers

Sometimes you want to exchange data with the backend without any specific shape being involved.

For such generic backend methods, you can use generic backend providers:

Add a src/backend.ts file and include it in tsconfig.json:

```json5
//tsconfig.json
{
  //...
  files: ['./src/index.ts', './src/backend.ts'],
}
```

In `backend.ts`, export a default class that implements `IBackendProvider`.
In this class you can implement methods, which you can then call from the frontend.

For example:

```typescript
//src/backend.ts
import { IBackendProvider } from 'lincd-server/lib/interfaces/IBackendProvider';

export default class MyPackageBackendProvider implements IBackendProvider {
  login(email: string, password: string) {
    //do login
    return Promise.resolve(user);
  }
}
```

With this example you could call the login method from the frontend like so:

```typescript
import { packageName } from '../package';
import { Server } from 'lincd-server/lib/utils/Server';

Server.call(packageName, 'login', email, password).then((user) => {
  //...
});
```

Note that you can have **only one** generic backend provider per package.

### Gotchas

**The packageName you pass to Server.call() must match with the package that contains the provider.**

If you get a warning on the backend saying

```
Generic provider [providerName] of [packageName] does not have a method called [methodName]
```

then make sure that the `packageName` you pass to `Server.call(packageName)` is imported from _the same package_ as
where the provider lives. Generally, this means you call `Server.call` from a component in the same package as the
Provider (and import packageName from `src/package.ts`). If you want to call a method from another package, then import
packageName from that package, or manually type it.

## Shapes

This section will be a brief overview of the shapes that are included in this package, along with example usage of each
shape.

### LocalFileStore

This is the default file store for LINCD. It is a simple file store that stores files in a local directory. Its usage
follows the general pattern of other file stores in LINCD:

- Define all storage locations when the server or application starts up
- Access methods of the file store through the `LinkedFileStorage` class
  - e.g. `LinkedFileStorage.saveFile("path/to/save-file.as", fileBuffer)`

It's important to note that this file store is not suitable for frontend usage - it's intended to be used in an
environment that has access to the [`fs` module](https://nodejs.org/api/fs.html).

```ts
import { LinkedFileStorage } from 'lincd/lib/utils/LinkedFileStorage';
import { LocalFileStore } from 'lincd-server/lib/shapes/LocalFileStore';
import path from 'path';

const pathToStore = path.join(process.cwd(), 'my-file-store');
const store = new LocalFileStore('my-file-store', pathToStore);
LinkedFileStorage.setDefaultStore(store);
```

## TODO

- [ ] Add tests
- [ ] Refactor `NodeFileStore` to `LocalQuadStore` as to not confuse FileStores with QuadStores

---
_Source: https://npm.io/package/lincd-server · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
