DEVELOPER DOCUMENTATION

Your first calendar.
Your own stack.

Use the JavaScript core directly or choose a framework wrapper. Add the optional PHP or ASP.NET Core server package when your application needs authenticated, durable event APIs.

Looking for an exact option, method, route, or default?

The generated API reference covers every client option and public calendar API, plus the complete PHP and ASP.NET Core route-level contracts.

Search the complete API reference →

1. Choose your frontend integration

Install command
npm install @wts-calendar/core

Mount the core into a browser element, then call destroy() when removing it.

Read JavaScript setup guide ↗

2. Add a backend when your application needs one

Frontend wrappers render the calendar. The PHP and ASP.NET Core packages implement the same server-side event REST contract while your application keeps control of authentication, authorization, and durable storage.

Composer install
composer require wts-calendar/server-php:^1.0 nyholm/psr7
Framework-neutral PHP handler
<?php

use Nyholm\Psr7\Factory\Psr17Factory;
use WtsCalendar\Server\CalendarApiHandler;
use WtsCalendar\Server\CalendarApiOptions;
use WtsCalendar\Server\CalendarEventStoreInterface;

$psr17 = new Psr17Factory();
$handler = new CalendarApiHandler(
    $container->get(CalendarEventStoreInterface::class),
    $psr17,
    $psr17,
    new CalendarApiOptions(
        requireIfMatchForUpdate: true,
        requireIfMatchForDelete: true,
    ),
);

// $request is the host application's PSR-7 ServerRequestInterface.
$response = $handler->handle($request);

Use any PSR-7 request, PSR-17 factories, and a durable CalendarEventStoreInterface implementation owned by your application.

Shared HTTP contract

MethodRoutePurpose
GET/api/calendar/events?start=...&end=...Load a bounded visible range
GET/api/calendar/events/{id}Load one event and its ETag
POST/api/calendar/eventsCreate an event
PATCH / PUT/api/calendar/events/{id}Update with If-Match conflict protection
DELETE/api/calendar/events/{id}Delete with an optional version precondition

The server package handles

  • Typed calendar event requests and responses
  • Range validation, CRUD routes, and RFC 7807 errors
  • ETag and If-Match optimistic concurrency
  • A replaceable storage interface

Your application still handles

  • Authentication and event-level authorization
  • Database schema, migrations, and tenant isolation
  • CORS origins, rate limits, secrets, and monitoring
  • Production storage; in-memory stores are demo-only

3. Connect every frontend to the same endpoint

Angular, React, and Vue use the core REST adapter. It carries mutation versions through ETag and If-Match so the server can reject stale edits. React Native calls the same authenticated JSON endpoint and passes the resulting events to its native component.

Angular, React and Vue data adapter
import {
  CalendarDataClient,
  createRestCalendarDataAdapter,
} from '@wts-calendar/core/data-adapter-sdk';

const endpoint = 'https://api.example.com/api/calendar/events';

export const calendarEvents = new CalendarDataClient(
  createRestCalendarDataAdapter({
    url: endpoint,
    mutationUrl: ({ type, id }) =>
      type === 'create'
        ? endpoint
        : `${endpoint}/${encodeURIComponent(id ?? '')}`,
    headers: async () => ({
      authorization: `Bearer ${await accessToken()}`,
    }),
  }),
);
React Native API loading
import { useEffect, useState } from 'react';
import { WtsCalendarNative } from '@wts-calendar/react-native';
import type { NativeCalendarEventInput } from '@wts-calendar/react-native';

const endpoint = 'https://api.example.com/api/calendar/events';

export function Schedule({ accessToken }: { accessToken: string }) {
  const [events, setEvents] = useState<readonly NativeCalendarEventInput[]>([]);

  useEffect(() => {
    const query = new URLSearchParams({
      start: '2026-09-01T00:00:00Z',
      end: '2026-10-01T00:00:00Z',
      timeZone: 'UTC',
    });
    fetch(`${endpoint}?${query}`, {
      headers: { authorization: `Bearer ${accessToken}` },
    })
      .then((response) => {
        if (!response.ok) throw new Error('Calendar request failed');
        return response.json();
      })
      .then((page) => setEvents(page.records));
  }, [accessToken]);

  return <WtsCalendarNative events={events} />;
}

4. Start with the core

This minimal JavaScript example uses only Standard features. Framework components manage mounting and teardown for you.

JavaScript / TypeScript
import { WtsCalendar } from '@wts-calendar/core';
import '@wts-calendar/core/styles/calendar.css';

const calendar = new WtsCalendar({
  container: document.querySelector('#calendar'),
  view: 'month',
  viewDate: '2026-09-07',
  events: [{ id: 'hello', title: 'Hello, calendar', start: '2026-09-07' }],
});

// On unmount:
// calendar.destroy();

5. Explore one feature at a time

The examples directory shows the feature options and runtime behavior together. Optional modules are loaded only for the relevant examples.

Open examples →
Runtime-only by design.

Sample events are stored in memory and reset when you reload or switch examples. This demo does not ask for provider credentials, store customer events, or run premium integrations.