create-an-edge-app
The recommended way to create an Edge App
SKILL.md
Full skill instructions
Creating an Edge App
When Creating an Edge App
- If you're one of the maintainers of this repository, it's encouraged to create the new Edge App in its own standalone GitHub repo under the Screenly org, rather than inside this monorepo's
edge-apps/directory. - Scaffold the new Edge App by starting from one of the apps in the Reference Apps section below — pick the closest match in complexity and adapt it, following the
kebab-casenaming convention for the app name. - After scaffolding, add an
idfield toscreenly.ymlandscreenly_qc.ymlbefore runningbun run dev. - Verify it boots before building features: run
bun run dev,bun run lint, and the tests. A scaffold that doesn't start is the first thing to fix. - Consult Figma designs before starting implementation.
- Ensure the Figma MCP server is set up in Claude Code.
- Use the Figma MCP server to access design specifications, mockups, and UI requirements.
- Extract design tokens such as colors, spacing, typography, and component specifications from Figma.
- Ensure the implementation matches the approved designs in Figma before proceeding with development.
Integrations and Authentication
When the app shows data from a third-party service, do not hand-roll an auth flow — that is where things go wrong. Screenly delivers credentials through one runtime call, and your job is only to feed that call locally.
- Declare each integration-backed value as a setting in
screenly.ymlwhosehelp_text.properties.typeisoauth:<provider>:<field>(e.g.oauth:google_calendar:access_token). The field is either a credential or config the user picked (which calendar, which dashboard). - Read credentials at runtime with a single call, refreshed on a loop — never reimplement the OAuth dance:
const { token, metadata } = await getCredentials() // from @screenly/edge-apps - See the Integrations section of the Edge Apps docs for the full contract.
To develop locally (real credentials aren't present), set up a super simple way to supply them — pick the lighter of these two:
- Read a secret (CLI is fine). Declare an
access_tokensecret marked "for testing only", set it withscreenly edge-app setting set access_token=...(or inmock-data.yml), and read it withgetSettingWithDefault('access_token', ''). See Screenly/google-calendar-app (src/main.ts). - Handle the OAuth flow with a tiny companion app. A small Express + Bun server that runs the flow, stores the tokens, refreshes them, and exposes
GET /access_token/returning{ token, metadata }— mimicking the Screenly OAuth service. Wire it in viamock-data.yml'sscreenly_oauth_tokens_url. See themock-authenticator/in Screenly/salesforce-app for a complete, minimal example.
Both paths feed the same getCredentials() — the Edge App code does not change between them.
Testing
- Write tests before the feature, then make them pass. Every app ships an
e2e/directory (Playwright); add cases there for the behavior you build. - For integration apps, test against mock credentials (the secret or the companion authenticator above), not a live account.
Before Opening a PR
- Generate and commit screenshots:
bun run screenshots(builds the app and captures all Screenly resolutions). This is required — seeedge-apps/CONTRIBUTING.md. - Keep
screenly_qc.ymlin sync with the app's settings and behavior. - Confirm
bun run lintand the tests pass.
Reference Apps
Most Edge Apps have migrated to standalone repos under the Screenly org. For reference on more complex implementations, consult:
- Screenly/qr-code-app — simple, low-footprint example
- Screenly/menu-board-app — more complex layout
- Screenly/cap-alerting-app — advanced settings and data fetching
- Screenly/google-calendar-app — integration via a test secret
- Screenly/salesforce-app — integration with a companion OAuth authenticator
All apps depend on the @screenly/edge-apps NPM package and use edge-apps-scripts for tooling.
About the Manifest Files
- Update the
categorieskey to reflect the app's purpose. - Add any app-specific settings under the
settingskey, sorted alphabetically. - More information about manifest files can be found in the Edge Apps documentation in the
Screenly/clirepository.
About index.html
- Organize HTML code into templates and Web Components as the app grows in complexity.
- Use HTML content templates first for simpler structures.
- Consider using Web Components for more complex UI components that require encapsulation and reusability.
About README.md
- Include instructions on how to create, build, test, format, lint, and deploy the app.
- Do not add details like the directory structure, as the code frequently changes.
