# namespace

> Declares the namespace a file's types belong to, written once at the top of the file. It is optional — a file without one puts its types in the global namespace. Names resolve against the namespace a file is written in, then any imported namespaces, then the always-available `Osyrin` core.

<!-- id: types-namespace · area: types · stability: stable · html: https://osysharp.com/reference/types/namespace/ -->

## Summary        {#summary}
A **namespace** groups a file's types under a common name, so two parts of an app can each have an `Order`
without colliding. Write it once, at the top of the file, terminated by a semicolon:

```osy syntax
namespace Shop.Catalog;
```

It is **optional**. A file with no `namespace` declaration puts its types in the **global namespace** — which is
exactly what a single-file app wants, and what every example in this reference assumes.

## Signature      {#signature}
```osy syntax
namespace Shop;              // this file's types are Shop.*
entity Order { … }           // → Shop.Order
```

## Description    {#description}

### What it does to a name   {#qualified-name}
A type declared in a namespace gets that namespace as a prefix. `namespace Shop;` followed by `entity Order`
declares **`Shop.Order`** — that is the type's real, full name, the one you use to refer to it from elsewhere.

Inside the file that declares it, you just write `Order`.

### Two forms — file-scoped and braced   {#forms}
Osy# supports both C# forms:

```osy title="file-scoped or braced — one form per file" syntax
namespace Shop;                          // file-scoped — opens the whole file (preferred)

namespace Shop { entity Order { … } }    // braced — opens just its block
namespace Billing { entity Order { … } } // several braced namespaces may share one file
```

- **File-scoped** (`namespace X;`) opens the whole file: it must come **before every other declaration**, and a
  file may declare **at most one**. Prefer it for a file that is all one namespace.
- **Braced** (`namespace X { … }`) opens just its block, so a file may hold **several** and they may **nest**
  (`namespace Shop { namespace Catalog { … } }` puts a type in `Shop.Catalog`). This is what lets C# code paste in
  verbatim.

A file uses **one form or the other, never both** — mixing a file-scoped `namespace X;` with a braced
`namespace Y { … }` in the same file is an error (as in C#).

### How a name resolves   {#resolution}
When you write a bare name, it is looked for in this order — the first match wins, and no later step can make it
ambiguous:

1. **The namespace you're in**, then each enclosing one, working outward. Inside `namespace Shop.Catalog;` that
   means `Shop.Catalog`, then `Shop`, then the global namespace.
2. **The namespaces you imported** with a `using` declaration — a package's, or one your own app declares. A
   `using` is PER FILE, and it imports that namespace's own types, never a child's: `using Shop;` does not bring
   in `Shop.Orders.Order` (write `using Shop.Orders;`). If *two* imports offer the same name, that is an error that
   names both — qualify the reference to say which you mean.
3. **The `Osyrin` core**, the platform's own namespace, always available without importing anything.

Because step 1 comes first, a type you declared always wins over one you imported. To reach the imported one
anyway, write its full name.

The same order holds for **every kind of name** — a type, a component, a control and a function alike. A component
of your own named like one in the UI kit is the one your namespace's pages get:

```osy title="your namespace's Badge, beside the kit's" syntax
namespace Acme.Lighting;
using Osysharp.Ui;

[Composable] component Badge(string text) { render { Text(text); } }

[Route("/")] component Home() {
  render { Badge(text: "on"); }      // Acme.Lighting.Badge — nearer than Osysharp.Ui.Badge
}
```

A namespace that encloses **neither** of two same-named declarations is still ambiguous there, and the error names
both full spellings.

**Two packages' functions of one name are told apart by their arguments**, as C# picks an overload: a call whose
arguments only ONE of them can take is that one, bare. Only a call that both could take — the same parameter list —
has to be qualified, and the error says so naming both. A qualified call works anywhere a call does, and so does a
`using` alias for the namespace:

```osy title="one name, two packages — the arguments choose" syntax
using Rota.Kit;       // SignUp(Shift shift, string who)
using Accounts.Kit;   // SignUp(string email, string password)
using R = Rota.Kit;

string Join(Shift s) => SignUp(s, "ada");                 // Rota.Kit's — only it takes a Shift
string Register() => SignUp("ada@x.test", "hunter22");    // Accounts.Kit's
string Drop() => Rota.Kit.Remove(1) + R.Remove(2);        // both kits have Remove(int): qualify, or alias
```

**A package's own call looks only among the packages it imports.** Code in a package resolves a bare call against
that package and the ones its own `package.osy` names with `use` — never against everything the app happens to use
beside it. So a kit that calls `NameOf(person)` from the one kit it depends on keeps compiling when an app also uses
an unrelated kit with a `NameOf` of its own. For the app's own code the packages are the ones its `app.osy` names.

`osy kits check` warns a kit's author when the kit exports a function with the same name and parameters as a kit
that is already published (`KIT_NAME_PUBLISHED`), since every app using both would have to qualify it. The thirteen built-in type names (`Markdown`, `Json`, `DateTime`, …) follow the same order: a
declaration in an enclosing namespace wins, and everywhere else the bare name is the built-in — see
[[types-name-shadowing#built-ins]].

### The `Osyrin` namespace is the platform's   {#osyrin}
Everything the platform ships lives under `Osyrin`. Its core types need no import. Its optional capabilities are
sub-namespaces — `Osysharp.Memory`, `Osysharp.Storage`, `Osysharp.Ui`, … — that you first **depend on** with a
[`use`](https://osysharp.com/reference/types/use/) in your `app { }` manifest, then **import** with a `using` in each file that references their
names. You cannot declare a type in `Osyrin` yourself.

### Reaching another namespace   {#qualifying}
A sibling namespace's types are not visible bare — qualify them, exactly as in C#:

```osy title="reaching a type in a sibling namespace" syntax
namespace Billing;

int Count() {
  var orders = Shop.Order.Where(o => o.Code == "x").ToList();   // qualified
  return orders.Count;
}
```

### Declaration names never contain a dot   {#no-dots}
`entity Shop.Order` is an error. A dot in a declared name is how you'd *spell* a namespace, not how you *declare*
one — use `namespace Shop;` at the top of the file.

## Examples       {#examples}
```osy title="a file written in a namespace" test app=types-namespace
using Osysharp.Markdown;

// catalog.osy
namespace Shop;

entity Order {
  [Required] string Code;
  decimal Total;
}

int OpenOrders() {
  // `Order` resolves to Shop.Order — the namespace this file is written in.
  return Order.Where(o => o.Total > 0).ToList().Count;
}
```

```osy title="reaching another namespace's type" test app=types-namespace
using Osysharp.Markdown;

// billing.osy — a different namespace, so Shop.Order must be qualified.
namespace Billing;

entity Invoice {
  Shop.Order Source;
  decimal Amount;
}
```

Step 3 applies in every position a type name can appear, including a property's type — a core type needs no import
there either:

```osy title="a core type by its bare name" test app=types-namespace
using Osysharp.Markdown;

namespace Filing;

entity Attachment {
  // `MarkdownDocument` is `Osysharp.Markdown.MarkdownDocument`, found at step 3. Nothing is imported and nothing is qualified.
  MarkdownDocument Body;
}
```

A `using` of a namespace your own app declares, then its types by their bare names:

```osy title="importing one of your own namespaces" test app=types-namespace-using
using Shop.Orders;

namespace Shop.Orders {
  public class Order { public string Code = ""; }
}

// This part of the file is in the global namespace; `Order` is found through the `using` above.
string CodeOf(Order order) {
  return order.Code;
}
```

## See also       {#see-also}
- [use](https://osysharp.com/reference/types/use/) — `use` declares the capability dependency in the manifest; `using` imports its names in a file.
- [type visibility (public / internal)](https://osysharp.com/reference/types/visibility/) — `public` and `internal` decide which of a namespace's types others can reach.
- [Osysharp.Ui (the UI kit)](https://osysharp.com/reference/ui/kit/) — `using` brings a kit's public types into scope under their bare names.
