# Quickstart > From zero to a deployed schema, a published entry, and a public read — with the CLI and SDK. This walkthrough takes you from nothing to a deployed schema, a published entry, and a public read. You need Node.js and a GitHub account. ## Install and sign in ```bash $ npm install --global @myna-sh/cli $ myna login # Opens app.myna.sh/device — sign in with GitHub and approve the device code. ``` `myna login` uses a browser device-authorization flow. The credential is stored in the macOS Keychain when available, otherwise in a user-only config file. ## Create and link a project ```bash $ myna organizations list $ myna projects create --name "My site" --organization my-org $ myna link my-site # Writes .myna/project.json (no secrets) so later commands know the project. ``` ## Define a schema `myna init` scaffolds a `myna/` directory with an example collection: ```ts import { collection, field } from "@myna-sh/sdk/schema"; export const posts = collection({ name: "posts", label: "Blog posts", visibility: "public", titleField: "title", path: "/blog/{slug}", fields: { title: field.text({ required: true, maxLength: 120 }), slug: field.slug({ from: "title", required: true }), description: field.text({ multiline: true }), body: field.markdown({ required: true }), cover: field.asset({ allowed: ["image/*"] }), publishedAt: field.datetime(), }, }); ``` Schemas are code-owned: the dashboard displays them but the source of truth is this file. Deploy it: ```bash $ myna schema diff $ myna schema push ``` `diff` shows a stable plan and classifies each operation; destructive changes require `--allow-destructive`. Every push creates an immutable schema version. ## Create and publish an entry ```bash $ myna entries create posts --set title="Hello world" --set body="First post." # Creates a draft revision on an implicit change set. Nothing is public yet. $ myna changes list $ myna changes publish --confirm-publish ``` Writes are drafts until a change set is published. Publishing validates every item and updates all published pointers in one transaction. ## Read published content ```ts import { createMyna } from "@myna-sh/sdk"; const myna = createMyna({ project: "my-site" }); const { data } = await myna.entries.list("posts", { order: "-publishedAt", limit: 10, }); const post = await myna.entries.get("posts", "hello-world"); ``` In a React app, [`@myna-sh/react`](/sdk/react) wraps the same client with hooks that share requests, carry loading and error state, and pass a preview token through the tree: ```tsx const { data, error, isLoading } = useMynaEntries("posts", { order: "-publishedAt" }); ``` Public collections need no credentials. Or use plain HTTP: ```bash $ curl https://api.myna.sh/v1/projects/my-site/collections/posts/entries ``` ## Generate types ```bash $ myna types generate --out src/myna.generated.ts ``` Emits deterministic TypeScript interfaces for your collections — same input, byte-identical output, safe to commit. Pass the generated registry to `createMyna` and reads are typed end to end: ```ts import { createMyna } from "@myna-sh/sdk"; import type { MynaCollections } from "./myna.generated"; const myna = createMyna({ project: "my-site" }); const { data } = await myna.entries.list("posts", { order: "-publishedAt" }); data[0].fields.title; // string ``` Collection keys, field names, and sortable fields are all checked — see [generated types](/schema/generated-types). ## Next - [Change sets and publishing](/concepts/change-sets) — the core workflow in depth. - [Using Myna with agents](/agents/workflow) — scoped keys, MCP setup, and the review loop.