Docs
CodeRabbit
Cloudflare
AG Grid
SerpAPI
Netlify
OpenRouter
Neon
WorkOS
Clerk
Electric
PowerSync
Sentry
Railway
Prisma
Strapi
Unkey
CodeRabbit
Cloudflare
AG Grid
SerpAPI
Netlify
OpenRouter
Neon
WorkOS
Clerk
Electric
PowerSync
Sentry
Railway
Prisma
Strapi
Unkey
Hotkeys API Reference
App Hotkeys API Reference
Key hold & held keys API Reference
Hotkey Recorder API Reference
Normalization & format API Reference

Lit Example: Hotkey Recorder

import { LitElement, css, html, nothing, unsafeCSS } from 'lit'
import { customElement, state } from 'lit/decorators.js'
import {
  HeldKeysController,
  HotkeyRecorderController,
  HotkeyRegistrationsController,
  formatForDisplay,
  getHotkeyManager,
} from '@tanstack/lit-hotkeys'
import appStyles from './index.css?raw'
import type { Hotkey, HotkeyRegistrationHandle } from '@tanstack/lit-hotkeys'

interface Shortcut {
  id: string
  name: string
  description: string
  hotkey: Hotkey | ''
}

let nextId = 0
function createId(): string {
  return `shortcut_${++nextId}`
}

const INITIAL_SHORTCUTS: Array<Shortcut> = [
  {
    id: createId(),
    name: 'Save',
    description: 'Save the current document',
    hotkey: 'Mod+K',
  },
  {
    id: createId(),
    name: 'Open',
    description: 'Open a file from disk',
    hotkey: 'Mod+E',
  },
  {
    id: createId(),
    name: 'New',
    description: 'Create a new document',
    hotkey: 'Mod+G',
  },
  {
    id: createId(),
    name: 'Close',
    description: 'Close the current tab',
    hotkey: 'Mod+Shift+K',
  },
  {
    id: createId(),
    name: 'Undo',
    description: 'Undo the last action',
    hotkey: 'Mod+Shift+E',
  },
  {
    id: createId(),
    name: 'Redo',
    description: 'Redo the last undone action',
    hotkey: 'Mod+Shift+G',
  },
]

@customElement('my-app')
export class MyApp extends LitElement {
  static styles = [
    css`
      :host {
        display: block;
        margin: 0;
        font-family:
          system-ui,
          -apple-system,
          sans-serif;
        background: #f5f5f5;
        color: #333;
        box-sizing: border-box;
      }
      :host *,
      :host *::before,
      :host *::after {
        box-sizing: border-box;
      }
    `,
    unsafeCSS(appStyles),
  ]

  private heldKeys = new HeldKeysController(this)
  private registrations = new HotkeyRegistrationsController(this)

  private recorder = new HotkeyRecorderController(this, {
    onRecord: (hotkey: Hotkey) => {
      if (this._editingId) {
        this._shortcuts = this._shortcuts.map((s) =>
          s.id === this._editingId
            ? {
                ...s,
                hotkey,
                name: this._draftName,
                description: this._draftDescription,
              }
            : s,
        )
        this._editingId = null
        this._reregisterHotkeys()
      }
    },
    onCancel: () => {
      // If this was a brand-new shortcut with no hotkey yet, remove it
      if (this._editingId) {
        const shortcut = this._shortcuts.find((s) => s.id === this._editingId)
        if (shortcut && shortcut.hotkey === '') {
          this._shortcuts = this._shortcuts.filter(
            (s) => s.id !== this._editingId,
          )
        }
      }
      this._editingId = null
      this._reregisterHotkeys()
    },
    onClear: () => {
      if (this._editingId) {
        this._shortcuts = this._shortcuts.map((s) =>
          s.id === this._editingId
            ? {
                ...s,
                hotkey: '',
                name: this._draftName,
                description: this._draftDescription,
              }
            : s,
        )
        this._editingId = null
        this._reregisterHotkeys()
      }
    },
  })

  @state() private _shortcuts: Array<Shortcut> = [...INITIAL_SHORTCUTS]
  @state() private _editingId: string | null = null
  @state() private _draftName = ''
  @state() private _draftDescription = ''

  private _hotkeyRegistrations: Array<HotkeyRegistrationHandle> = []

  override connectedCallback(): void {
    super.connectedCallback()
    this._reregisterHotkeys()
  }

  override disconnectedCallback(): void {
    super.disconnectedCallback()
    this._unregisterAll()
  }

  private _unregisterAll(): void {
    for (const reg of this._hotkeyRegistrations) {
      if (reg.isActive) {
        reg.unregister()
      }
    }
    this._hotkeyRegistrations = []
  }

  private _reregisterHotkeys(): void {
    this._unregisterAll()

    const manager = getHotkeyManager()

    for (const shortcut of this._shortcuts) {
      if (shortcut.hotkey === '') continue

      const reg = manager.register(
        shortcut.hotkey,
        () => {
          console.log(`${shortcut.name} triggered:`, shortcut.hotkey)
        },
        {
          target: document,
          meta: {
            name: shortcut.name,
            description: shortcut.description,
          },
        },
      )
      this._hotkeyRegistrations.push(reg)
    }
  }

  private _handleEdit(id: string): void {
    const shortcut = this._shortcuts.find((s) => s.id === id)
    if (!shortcut) return
    this._editingId = id
    this._draftName = shortcut.name
    this._draftDescription = shortcut.description
    this.recorder.startRecording()
  }

  private _handleSaveEditing(): void {
    if (this._editingId) {
      this._shortcuts = this._shortcuts.map((s) =>
        s.id === this._editingId
          ? { ...s, name: this._draftName, description: this._draftDescription }
          : s,
      )
      this.recorder.stopRecording()
      this._editingId = null
      this._reregisterHotkeys()
    }
  }

  private _handleCancel(): void {
    this.recorder.cancelRecording()
    // onCancel callback handles cleanup
  }

  private _handleDelete(id: string): void {
    this._shortcuts = this._shortcuts.filter((s) => s.id !== id)
    this._reregisterHotkeys()
  }

  private _handleCreateNew(): void {
    const newShortcut: Shortcut = {
      id: createId(),
      name: '',
      description: '',
      hotkey: '',
    }
    this._shortcuts = [...this._shortcuts, newShortcut]
    this._editingId = newShortcut.id
    this._draftName = ''
    this._draftDescription = ''
    this.recorder.startRecording()
  }

  render() {
    return html`
      <div class="app">
        <header>
          <h1>Keyboard Shortcuts Settings</h1>
          <p>
            Customize your keyboard shortcuts. Click "Edit" to record a new
            shortcut, or press Escape to cancel.
          </p>
        </header>

        <main>
          <section class="demo-section">
            <h2>Shortcuts</h2>
            <div class="shortcuts-list">
              ${this._shortcuts.map((shortcut) => {
                const isEditing = this._editingId === shortcut.id
                const displayName = isEditing ? this._draftName : shortcut.name
                const displayDescription = isEditing
                  ? this._draftDescription
                  : shortcut.description

                return html`
                  <div class="shortcut-item ${isEditing ? 'recording' : ''}">
                    <div class="shortcut-item-content">
                      <div class="shortcut-action">
                        ${
                          isEditing
                            ? html`
                                <div class="editing-fields">
                                  <input
                                    type="text"
                                    class="edit-input edit-name"
                                    .value=${displayName}
                                    @input=${(e: InputEvent) =>
                                      (this._draftName = (
                                        e.target as HTMLInputElement
                                      ).value)}
                                    placeholder="Shortcut name"
                                  />
                                  <input
                                    type="text"
                                    class="edit-input edit-description"
                                    .value=${displayDescription}
                                    @input=${(e: InputEvent) =>
                                      (this._draftDescription = (
                                        e.target as HTMLInputElement
                                      ).value)}
                                    placeholder="Description (optional)"
                                  />
                                </div>
                              `
                            : html`
                                ${
                                  shortcut.name ||
                                  html`<span class="unnamed">Unnamed</span>`
                                }
                                ${
                                  shortcut.description
                                    ? html`<div class="shortcut-description">
                                        ${shortcut.description}
                                      </div>`
                                    : nothing
                                }
                              `
                        }
                      </div>
                      <div class="shortcut-hotkey">
                        ${
                          isEditing
                            ? html`
                                <div class="recording-indicator">
                                  ${
                                    this.heldKeys.value.length > 0
                                      ? html`
                                          <div class="held-hotkeys">
                                            ${this.heldKeys.value.map(
                                              (key, index) => html`
                                                ${
                                                  index > 0
                                                    ? html`<span class="plus"
                                                        >+</span
                                                      >`
                                                    : nothing
                                                }
                                                <kbd>${key}</kbd>
                                              `,
                                            )}
                                          </div>
                                        `
                                      : html`
                                          <span class="recording-text">
                                            Press any key combination...
                                          </span>
                                        `
                                  }
                                </div>
                              `
                            : shortcut.hotkey
                              ? html`<kbd
                                  >${formatForDisplay(shortcut.hotkey)}</kbd
                                >`
                              : html`<span class="no-shortcut"
                                  >No shortcut</span
                                >`
                        }
                      </div>
                    </div>
                    <div class="shortcut-actions">
                      ${
                        isEditing
                          ? html`
                              <button
                                class="save-button"
                                @click=${() => this._handleSaveEditing()}
                              >
                                Save
                              </button>
                              <button
                                class="cancel-button"
                                @click=${() => this._handleCancel()}
                              >
                                Cancel
                              </button>
                            `
                          : html`
                              <button
                                class="edit-button"
                                @click=${() => this._handleEdit(shortcut.id)}
                              >
                                Edit
                              </button>
                              <button
                                class="delete-button"
                                @click=${() => this._handleDelete(shortcut.id)}
                              >
                                Delete
                              </button>
                            `
                      }
                    </div>
                  </div>
                `
              })}
            </div>
            <button
              class="create-button"
              @click=${() => this._handleCreateNew()}
              ?disabled=${this.recorder.isRecording}
            >
              + Create New Shortcut
            </button>
          </section>

          ${
            this.recorder.isRecording
              ? html`
                  <div class="info-box recording-notice">
                    <strong>Recording shortcut...</strong> Press any key
                    combination or Escape to cancel. Press Backspace/Delete to
                    clear the shortcut.
                  </div>
                `
              : nothing
          }

          <section class="demo-section">
            <h2>Live Registrations</h2>
            <p>
              This table is powered by
              <code>HotkeyRegistrationsController</code> — trigger counts,
              names, and descriptions update in real-time as you use your
              shortcuts.
            </p>
            <table class="registrations-table">
              <thead>
                <tr>
                  <th>Hotkey</th>
                  <th>Name</th>
                  <th>Description</th>
                  <th>Enabled</th>
                  <th>Triggers</th>
                </tr>
              </thead>
              <tbody>
                ${this.registrations.hotkeys.map(
                  (reg) => html`
                    <tr>
                      <td>
                        <kbd>${formatForDisplay(reg.hotkey)}</kbd>
                      </td>
                      <td>${reg.options.meta?.name ?? '\u2014'}</td>
                      <td class="description-cell">
                        ${reg.options.meta?.description ?? '\u2014'}
                      </td>
                      <td>
                        <span
                          class=${
                            reg.options.enabled !== false
                              ? 'status-on'
                              : 'status-off'
                          }
                        >
                          ${reg.options.enabled !== false ? 'yes' : 'no'}
                        </span>
                      </td>
                      <td class="trigger-count">${reg.triggerCount}</td>
                    </tr>
                  `,
                )}
                ${
                  this.registrations.hotkeys.length === 0
                    ? html`
                        <tr>
                          <td colspan="5" class="empty-row">
                            No hotkeys registered
                          </td>
                        </tr>
                      `
                    : nothing
                }
              </tbody>
            </table>
          </section>

          <section class="demo-section">
            <h2>Usage</h2>
            <pre class="code-block">
${`import {
  HotkeyRecorderController,
  HotkeyRegistrationsController,
  formatForDisplay,
  getHotkeyManager,
} from '@tanstack/lit-hotkeys'
import type { Hotkey } from '@tanstack/lit-hotkeys'

class ShortcutSettings extends LitElement {
  private recorder = new HotkeyRecorderController(this, {
    onRecord: (hotkey) => {
      this.shortcut = hotkey
      this.requestUpdate()
    },
    onCancel: () => {
      console.log('Recording cancelled')
    },
  })

  private registrations = new HotkeyRegistrationsController(this)

  // Register with meta for display in registrations viewer
  const reg = manager.register(hotkey, callback, {
    meta: { name: 'Save', description: 'Save the document' },
  })

  // Read all registrations reactively
  // this.registrations.hotkeys[0].options.meta?.name → 'Save'
  // this.registrations.hotkeys[0].triggerCount → 3
}`}</pre>
          </section>
        </main>
      </div>
    `
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'my-app': MyApp
  }
}
import { LitElement, css, html, nothing, unsafeCSS } from 'lit'
import { customElement, state } from 'lit/decorators.js'
import {
  HeldKeysController,
  HotkeyRecorderController,
  HotkeyRegistrationsController,
  formatForDisplay,
  getHotkeyManager,
} from '@tanstack/lit-hotkeys'
import appStyles from './index.css?raw'
import type { Hotkey, HotkeyRegistrationHandle } from '@tanstack/lit-hotkeys'

interface Shortcut {
  id: string
  name: string
  description: string
  hotkey: Hotkey | ''
}

let nextId = 0
function createId(): string {
  return `shortcut_${++nextId}`
}

const INITIAL_SHORTCUTS: Array<Shortcut> = [
  {
    id: createId(),
    name: 'Save',
    description: 'Save the current document',
    hotkey: 'Mod+K',
  },
  {
    id: createId(),
    name: 'Open',
    description: 'Open a file from disk',
    hotkey: 'Mod+E',
  },
  {
    id: createId(),
    name: 'New',
    description: 'Create a new document',
    hotkey: 'Mod+G',
  },
  {
    id: createId(),
    name: 'Close',
    description: 'Close the current tab',
    hotkey: 'Mod+Shift+K',
  },
  {
    id: createId(),
    name: 'Undo',
    description: 'Undo the last action',
    hotkey: 'Mod+Shift+E',
  },
  {
    id: createId(),
    name: 'Redo',
    description: 'Redo the last undone action',
    hotkey: 'Mod+Shift+G',
  },
]

@customElement('my-app')
export class MyApp extends LitElement {
  static styles = [
    css`
      :host {
        display: block;
        margin: 0;
        font-family:
          system-ui,
          -apple-system,
          sans-serif;
        background: #f5f5f5;
        color: #333;
        box-sizing: border-box;
      }
      :host *,
      :host *::before,
      :host *::after {
        box-sizing: border-box;
      }
    `,
    unsafeCSS(appStyles),
  ]

  private heldKeys = new HeldKeysController(this)
  private registrations = new HotkeyRegistrationsController(this)

  private recorder = new HotkeyRecorderController(this, {
    onRecord: (hotkey: Hotkey) => {
      if (this._editingId) {
        this._shortcuts = this._shortcuts.map((s) =>
          s.id === this._editingId
            ? {
                ...s,
                hotkey,
                name: this._draftName,
                description: this._draftDescription,
              }
            : s,
        )
        this._editingId = null
        this._reregisterHotkeys()
      }
    },
    onCancel: () => {
      // If this was a brand-new shortcut with no hotkey yet, remove it
      if (this._editingId) {
        const shortcut = this._shortcuts.find((s) => s.id === this._editingId)
        if (shortcut && shortcut.hotkey === '') {
          this._shortcuts = this._shortcuts.filter(
            (s) => s.id !== this._editingId,
          )
        }
      }
      this._editingId = null
      this._reregisterHotkeys()
    },
    onClear: () => {
      if (this._editingId) {
        this._shortcuts = this._shortcuts.map((s) =>
          s.id === this._editingId
            ? {
                ...s,
                hotkey: '',
                name: this._draftName,
                description: this._draftDescription,
              }
            : s,
        )
        this._editingId = null
        this._reregisterHotkeys()
      }
    },
  })

  @state() private _shortcuts: Array<Shortcut> = [...INITIAL_SHORTCUTS]
  @state() private _editingId: string | null = null
  @state() private _draftName = ''
  @state() private _draftDescription = ''

  private _hotkeyRegistrations: Array<HotkeyRegistrationHandle> = []

  override connectedCallback(): void {
    super.connectedCallback()
    this._reregisterHotkeys()
  }

  override disconnectedCallback(): void {
    super.disconnectedCallback()
    this._unregisterAll()
  }

  private _unregisterAll(): void {
    for (const reg of this._hotkeyRegistrations) {
      if (reg.isActive) {
        reg.unregister()
      }
    }
    this._hotkeyRegistrations = []
  }

  private _reregisterHotkeys(): void {
    this._unregisterAll()

    const manager = getHotkeyManager()

    for (const shortcut of this._shortcuts) {
      if (shortcut.hotkey === '') continue

      const reg = manager.register(
        shortcut.hotkey,
        () => {
          console.log(`${shortcut.name} triggered:`, shortcut.hotkey)
        },
        {
          target: document,
          meta: {
            name: shortcut.name,
            description: shortcut.description,
          },
        },
      )
      this._hotkeyRegistrations.push(reg)
    }
  }

  private _handleEdit(id: string): void {
    const shortcut = this._shortcuts.find((s) => s.id === id)
    if (!shortcut) return
    this._editingId = id
    this._draftName = shortcut.name
    this._draftDescription = shortcut.description
    this.recorder.startRecording()
  }

  private _handleSaveEditing(): void {
    if (this._editingId) {
      this._shortcuts = this._shortcuts.map((s) =>
        s.id === this._editingId
          ? { ...s, name: this._draftName, description: this._draftDescription }
          : s,
      )
      this.recorder.stopRecording()
      this._editingId = null
      this._reregisterHotkeys()
    }
  }

  private _handleCancel(): void {
    this.recorder.cancelRecording()
    // onCancel callback handles cleanup
  }

  private _handleDelete(id: string): void {
    this._shortcuts = this._shortcuts.filter((s) => s.id !== id)
    this._reregisterHotkeys()
  }

  private _handleCreateNew(): void {
    const newShortcut: Shortcut = {
      id: createId(),
      name: '',
      description: '',
      hotkey: '',
    }
    this._shortcuts = [...this._shortcuts, newShortcut]
    this._editingId = newShortcut.id
    this._draftName = ''
    this._draftDescription = ''
    this.recorder.startRecording()
  }

  render() {
    return html`
      <div class="app">
        <header>
          <h1>Keyboard Shortcuts Settings</h1>
          <p>
            Customize your keyboard shortcuts. Click "Edit" to record a new
            shortcut, or press Escape to cancel.
          </p>
        </header>

        <main>
          <section class="demo-section">
            <h2>Shortcuts</h2>
            <div class="shortcuts-list">
              ${this._shortcuts.map((shortcut) => {
                const isEditing = this._editingId === shortcut.id
                const displayName = isEditing ? this._draftName : shortcut.name
                const displayDescription = isEditing
                  ? this._draftDescription
                  : shortcut.description

                return html`
                  <div class="shortcut-item ${isEditing ? 'recording' : ''}">
                    <div class="shortcut-item-content">
                      <div class="shortcut-action">
                        ${
                          isEditing
                            ? html`
                                <div class="editing-fields">
                                  <input
                                    type="text"
                                    class="edit-input edit-name"
                                    .value=${displayName}
                                    @input=${(e: InputEvent) =>
                                      (this._draftName = (
                                        e.target as HTMLInputElement
                                      ).value)}
                                    placeholder="Shortcut name"
                                  />
                                  <input
                                    type="text"
                                    class="edit-input edit-description"
                                    .value=${displayDescription}
                                    @input=${(e: InputEvent) =>
                                      (this._draftDescription = (
                                        e.target as HTMLInputElement
                                      ).value)}
                                    placeholder="Description (optional)"
                                  />
                                </div>
                              `
                            : html`
                                ${
                                  shortcut.name ||
                                  html`<span class="unnamed">Unnamed</span>`
                                }
                                ${
                                  shortcut.description
                                    ? html`<div class="shortcut-description">
                                        ${shortcut.description}
                                      </div>`
                                    : nothing
                                }
                              `
                        }
                      </div>
                      <div class="shortcut-hotkey">
                        ${
                          isEditing
                            ? html`
                                <div class="recording-indicator">
                                  ${
                                    this.heldKeys.value.length > 0
                                      ? html`
                                          <div class="held-hotkeys">
                                            ${this.heldKeys.value.map(
                                              (key, index) => html`
                                                ${
                                                  index > 0
                                                    ? html`<span class="plus"
                                                        >+</span
                                                      >`
                                                    : nothing
                                                }
                                                <kbd>${key}</kbd>
                                              `,
                                            )}
                                          </div>
                                        `
                                      : html`
                                          <span class="recording-text">
                                            Press any key combination...
                                          </span>
                                        `
                                  }
                                </div>
                              `
                            : shortcut.hotkey
                              ? html`<kbd
                                  >${formatForDisplay(shortcut.hotkey)}</kbd
                                >`
                              : html`<span class="no-shortcut"
                                  >No shortcut</span
                                >`
                        }
                      </div>
                    </div>
                    <div class="shortcut-actions">
                      ${
                        isEditing
                          ? html`
                              <button
                                class="save-button"
                                @click=${() => this._handleSaveEditing()}
                              >
                                Save
                              </button>
                              <button
                                class="cancel-button"
                                @click=${() => this._handleCancel()}
                              >
                                Cancel
                              </button>
                            `
                          : html`
                              <button
                                class="edit-button"
                                @click=${() => this._handleEdit(shortcut.id)}
                              >
                                Edit
                              </button>
                              <button
                                class="delete-button"
                                @click=${() => this._handleDelete(shortcut.id)}
                              >
                                Delete
                              </button>
                            `
                      }
                    </div>
                  </div>
                `
              })}
            </div>
            <button
              class="create-button"
              @click=${() => this._handleCreateNew()}
              ?disabled=${this.recorder.isRecording}
            >
              + Create New Shortcut
            </button>
          </section>

          ${
            this.recorder.isRecording
              ? html`
                  <div class="info-box recording-notice">
                    <strong>Recording shortcut...</strong> Press any key
                    combination or Escape to cancel. Press Backspace/Delete to
                    clear the shortcut.
                  </div>
                `
              : nothing
          }

          <section class="demo-section">
            <h2>Live Registrations</h2>
            <p>
              This table is powered by
              <code>HotkeyRegistrationsController</code> — trigger counts,
              names, and descriptions update in real-time as you use your
              shortcuts.
            </p>
            <table class="registrations-table">
              <thead>
                <tr>
                  <th>Hotkey</th>
                  <th>Name</th>
                  <th>Description</th>
                  <th>Enabled</th>
                  <th>Triggers</th>
                </tr>
              </thead>
              <tbody>
                ${this.registrations.hotkeys.map(
                  (reg) => html`
                    <tr>
                      <td>
                        <kbd>${formatForDisplay(reg.hotkey)}</kbd>
                      </td>
                      <td>${reg.options.meta?.name ?? '\u2014'}</td>
                      <td class="description-cell">
                        ${reg.options.meta?.description ?? '\u2014'}
                      </td>
                      <td>
                        <span
                          class=${
                            reg.options.enabled !== false
                              ? 'status-on'
                              : 'status-off'
                          }
                        >
                          ${reg.options.enabled !== false ? 'yes' : 'no'}
                        </span>
                      </td>
                      <td class="trigger-count">${reg.triggerCount}</td>
                    </tr>
                  `,
                )}
                ${
                  this.registrations.hotkeys.length === 0
                    ? html`
                        <tr>
                          <td colspan="5" class="empty-row">
                            No hotkeys registered
                          </td>
                        </tr>
                      `
                    : nothing
                }
              </tbody>
            </table>
          </section>

          <section class="demo-section">
            <h2>Usage</h2>
            <pre class="code-block">
${`import {
  HotkeyRecorderController,
  HotkeyRegistrationsController,
  formatForDisplay,
  getHotkeyManager,
} from '@tanstack/lit-hotkeys'
import type { Hotkey } from '@tanstack/lit-hotkeys'

class ShortcutSettings extends LitElement {
  private recorder = new HotkeyRecorderController(this, {
    onRecord: (hotkey) => {
      this.shortcut = hotkey
      this.requestUpdate()
    },
    onCancel: () => {
      console.log('Recording cancelled')
    },
  })

  private registrations = new HotkeyRegistrationsController(this)

  // Register with meta for display in registrations viewer
  const reg = manager.register(hotkey, callback, {
    meta: { name: 'Save', description: 'Save the document' },
  })

  // Read all registrations reactively
  // this.registrations.hotkeys[0].options.meta?.name → 'Save'
  // this.registrations.hotkeys[0].triggerCount → 3
}`}</pre>
          </section>
        </main>
      </div>
    `
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'my-app': MyApp
  }
}