# How to Extend Logto's Functionality: A Developer's Guide to Custom Connectors and Inline Hooks

> Extend Logto's functionality with custom connectors or inline hooks. Build self-contained Node.js packages and JavaScript functions to customize authentication without altering core code.

- Repository: [Logto/logto](https://github.com/logto-io/logto)
- Tags: how-to-guide
- Published: 2026-07-06

---

**You can extend Logto's functionality by creating custom connectors (self-contained Node.js packages for identity/email/SMS providers) or implementing inline hooks (JavaScript functions that execute during authentication events) without modifying core code.**

Logto is architected as a modular, extensible platform where the core runtime remains stable while integration points allow customization. The primary extension mechanisms reside in `packages/connectors` for third-party service integrations and `packages/schemas` along with [`packages/core/src/libraries/inline-hook.ts`](https://github.com/logto-io/logto/blob/main/packages/core/src/libraries/inline-hook.ts) for runtime customization logic. These extension points let you add new identity providers, messaging services, or custom validation logic while maintaining compatibility with upstream updates.

## Understanding Logto's Extension Architecture

Logto separates concerns between its immutable core and pluggable extensions. The **core runtime** lives in `packages/core` and handles authentication flows, session management, and user storage. **Connectors** are self-contained Node.js packages that bridge Logto to external services like OAuth providers or SMS gateways. **Inline hooks** are JavaScript functions executed in a sandboxed VM during specific authentication lifecycle events, allowing you to modify user objects or enforce custom policies.

The key source files defining these extension contracts include [`packages/toolkit/connector-kit/src/index.ts`](https://github.com/logto-io/logto/blob/main/packages/toolkit/connector-kit/src/index.ts) (providing typed helpers like `ConnectorError` and `jsonGuard`), [`packages/schemas/src/types/logto-config/inline-hook.ts`](https://github.com/logto-io/logto/blob/main/packages/schemas/src/types/logto-config/inline-hook.ts) (Zod schemas for hook payloads), and [`packages/core/src/libraries/inline-hook.ts`](https://github.com/logto-io/logto/blob/main/packages/core/src/libraries/inline-hook.ts) (the runtime execution engine).

## Creating Custom Connectors

Connectors are the primary way to extend Logto's functionality for identity verification and messaging. Each connector is a standalone package under `packages/connectors/` that implements a consistent interface.

### Connector Structure and Requirements

Every connector follows a standardized template synchronized from [`templates/package.json`](https://github.com/logto-io/logto/blob/main/templates/package.json) via the `pnpm:devPreinstall` script. Required files include:
- [`package.json`](https://github.com/logto-io/logto/blob/main/package.json) with `"main": "src/index.ts"` pointing to your entry point
- Implementation of provider-specific functions like `sendVerificationCode` or `verifyCode`
- Error handling using `ConnectorError` and `ConnectorErrorCodes` from `@logto/connector-kit`

### Implementation Steps

1. **Create the package directory** under `packages/connectors/` (e.g., `connector-custom-sms`).

2. **Initialize from template** by running `pnpm i`, which syncs boilerplate fields from the central template.

3. **Implement required functions** in [`src/index.ts`](https://github.com/logto-io/logto/blob/main/src/index.ts). For an SMS connector, you must export `sendVerificationCode`:

```typescript
// packages/connectors/connector-custom-sms/src/index.ts
import { ConnectorError, ConnectorErrorCodes } from '@logto/connector-kit';
import ky from 'ky';

export const sendVerificationCode = async (phone: string, code: string) => {
  const res = await ky.post('https://api.custom-sms.com/send', {
    json: { to: phone, message: `Your code: ${code}` },
  }).json();

  if (res.status !== 'ok') {
    throw new ConnectorError(ConnectorErrorCodes.General, 'SMS delivery failed');
  }
};

```

4. **Build the package** using `pnpm build` to compile TypeScript.

5. **Register via Console UI** by navigating to Tenant → Connectors → Add Connector, or use the Management API as shown below.

## Implementing Inline Hooks

Inline hooks let you extend Logto's functionality by injecting custom JavaScript into authentication flows without deploying new packages. These scripts execute in a sandboxed VM during specific events like post-first-factor verification or post-sign-in.

### Hook Types and Payloads

The available hook types are defined in [`packages/schemas/src/types/logto-config/inline-hook.ts`](https://github.com/logto-io/logto/blob/main/packages/schemas/src/types/logto-config/inline-hook.ts) using Zod schemas. Common triggers include:
- `inlineHook.postFirstFactorVerification`: Runs after password/OTP verification
- `inlineHook.postSignIn`: Executes after successful authentication

Each hook receives a typed payload containing the user object, identifiers, and verification status.

### Writing and Deploying Hook Scripts

Create a JavaScript file that exports a `runInlineHook` function receiving the event payload:

```javascript
// scripts/post-signin-add-claim.js
async function runInlineHook(payload) {
  const { user } = payload; // user follows HookUser type from schemas
  
  return {
    action: 'updateUser',
    user: { customData: { welcomeBack: true } },
  };
}

module.exports = { runInlineHook };

```

Deploy the hook using the Admin API endpoint defined in [`packages/core/src/routes/logto-config/inline-hook.ts`](https://github.com/logto-io/logto/blob/main/packages/core/src/routes/logto-config/inline-hook.ts):

```bash
curl -X POST https://localhost:3002/api/connector/inline-hooks \
  -H "Authorization: Bearer <admin-token>" \
  -H "Content-Type: application/json" \
  -d '{
    "hookType": "inlineHook.postFirstFactorVerification",
    "script": "$(cat scripts/post-first-factor.js)",
    "enabled": true,
    "onExecutionError": "block"
  }'

```

The `InlineHookLibrary` in [`packages/core/src/libraries/inline-hook.ts`](https://github.com/logto-io/logto/blob/main/packages/core/src/libraries/inline-hook.ts) loads your script into a VM and executes it during the specified authentication phase. If `onExecutionError` is set to `"block"`, authentication fails when the hook throws an error.

## Advanced Extension: Adding Custom Hook Events

For deeper integration requiring new event types, you can extend the core by modifying [`packages/schemas/src/foundations/jsonb-types/hooks.ts`](https://github.com/logto-io/logto/blob/main/packages/schemas/src/foundations/jsonb-types/hooks.ts) to add new `HookEvent` constants. Update the database schema in [`packages/schemas/tables/hooks.sql`](https://github.com/logto-io/logto/blob/main/packages/schemas/tables/hooks.sql) and implement handling in [`packages/core/src/libraries/inline-hook.ts`](https://github.com/logto-io/logto/blob/main/packages/core/src/libraries/inline-hook.ts). This approach requires maintaining a forked version of Logto and migrating database changes.

## Programmatic Connector Registration

You can automate connector deployment using the Logto Management SDK instead of the Console UI:

```typescript
import { ManagementApi } from '@logto/sdk';

const api = new ManagementApi('https://localhost:3002', '<admin-token>');
await api.connectors.create({
  connectorId: 'custom-sms',
  config: { apiKey: 'xxxx' },
});

```

This method is particularly useful for infrastructure-as-code setups or multi-tenant environments where you need to extend Logto's functionality across multiple instances.

## Summary

- **Custom connectors** are self-contained Node.js packages in `packages/connectors/` that implement standardized functions for external service integration.
- **Inline hooks** are JavaScript functions uploaded via the Admin API ([`packages/core/src/routes/logto-config/inline-hook.ts`](https://github.com/logto-io/logto/blob/main/packages/core/src/routes/logto-config/inline-hook.ts)) that execute during specific authentication events.
- The **connector SDK** ([`packages/toolkit/connector-kit/src/index.ts`](https://github.com/logto-io/logto/blob/main/packages/toolkit/connector-kit/src/index.ts)) provides typed utilities like `ConnectorError` for robust error handling.
- **Registration** occurs through the Console UI or Management API after building connectors with `pnpm build`.
- **Core modification** requires editing schema files in `packages/schemas` and runtime logic in [`packages/core/src/libraries/inline-hook.ts`](https://github.com/logto-io/logto/blob/main/packages/core/src/libraries/inline-hook.ts) for entirely new event types.

## Frequently Asked Questions

### What is the difference between a connector and an inline hook?

A **connector** is a permanent package integration for external services like email providers or social identity platforms, requiring build and deployment steps. An **inline hook** is a runtime JavaScript snippet uploaded through the API that executes during specific authentication events to modify user data or enforce custom logic without redeploying Logto.

### Can I extend Logto's functionality without forking the repository?

Yes. You can extend Logto's functionality using **custom connectors** (created as separate packages under `packages/connectors/` and built with `pnpm build`) or **inline hooks** (uploaded via the Admin API). Both methods work with the standard Logto distribution and do not require modifying core source files.

### How do I handle errors in custom connectors?

Import `ConnectorError` and `ConnectorErrorCodes` from `@logto/connector-kit` and throw specific errors in your implementation functions. For example: `throw new ConnectorError(ConnectorErrorCodes.General, 'SMS delivery failed')`. These errors propagate through Logto's core and display appropriate messages to end users.

### Where are inline hook scripts stored and executed?

Inline hook scripts are stored in the Logto database and executed by the `InlineHookLibrary` class in [`packages/core/src/libraries/inline-hook.ts`](https://github.com/logto-io/logto/blob/main/packages/core/src/libraries/inline-hook.ts). The library creates a sandboxed VM context for each execution, enforces payload schemas defined in [`packages/schemas/src/types/logto-config/inline-hook.ts`](https://github.com/logto-io/logto/blob/main/packages/schemas/src/types/logto-config/inline-hook.ts), and handles the return values to determine whether to proceed with or block the authentication flow.