# Build your own


> An app is a web app plus a manifest. What you get from packaging it as an app rather than pointing a screen at a URL.
If nothing in the store fits, build it. A custom app runs on Screenly like any other content, and the logic and the look are yours.

## What one is

A standard web application, an `index.html` with its CSS and JavaScript, plus a `screenly.yml` manifest describing its name, its settings, and its secrets.

```text
my-app/
  index.html
  screenly.yml
  styles.css
  app.js
```

You write it the way you would write any web page. It runs in a browser on the player.

## Why bother, rather than pointing a screen at a URL

Everything around the code.

**Configuration in the dashboard.** The manifest declares the fields, and a non-technical colleague sets it up without touching anything you wrote.

**Secrets.** An API key goes in encrypted and never appears in the page source. See [Settings and secrets](/docs/apps/setting-up/settings-and-secrets/).

**Versioned deploys across a fleet.** One command updates every screen running it.

**A CORS proxy.** Apps can fetch from APIs that would otherwise block a browser request, with no proxy of your own to run.

**Branding.** The app reads your workspace logo and colors rather than having them hard-coded.

If you need none of those, a web page is simpler and perfectly legitimate.

## The workflow

```bash
screenly edge-app validate
screenly edge-app run --generate-mock-data
screenly edge-app deploy
```

Build locally, run against mock data without deploying, then deploy. It is non-interactive, so it drops into GitHub Actions or any other pipeline, and the whole app is plain text that commits cleanly to git.

## Where the detail is

The manifest schema, the JavaScript API available to your app, the branding values, and the deploy model are all in [Edge apps](/docs/developers/edge-apps/) and at [developer.screenly.io](https://developer.screenly.io/edge-apps/).