# type visibility (public / internal)

> A top-level type carries a public or internal visibility that decides whether code outside its namespace can name it. The default depends on what you declared: an entity or enum is public, a class is internal (exactly C#). A component has no visibility modifier at all — its access is governed by authorization.

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

## Summary        {#summary}
Every top-level type has a **visibility** that decides whether code outside its namespace can name it. A
**`public`** type is part of the surface its namespace offers outward; an **`internal`** type is an
implementation detail, usable freely inside its own namespace and invisible beyond it.

You rarely have to write the modifier, because the **default follows what you declared**: an `entity` or an
`enum` is public, a `class` is internal. A `component` has no visibility modifier at all.

## Signature      {#signature}
```osy syntax
entity Product { string Name; }            // public — an entity is a data surface
enum Status { Draft, Active }              // public — an enum is vocabulary
class Money { public decimal Amount; }     // internal — exactly C#

internal entity Ledger { … }               // an entity kept inside its namespace
public class Money { … }                   // a class offered outward
component Badge(string label) { … }        // no modifier — see below
```

## Description    {#description}

### The defaults, and why they differ   {#defaults}
| You declare | Default | Why |
|---|---|---|
| `entity` | `public` | An entity **is** the app's data surface — its fields are already public, so the type is too. |
| `enum` | `public` | An enum is vocabulary: it appears as the field type of a public entity, so an internal default would create friction at every use. |
| `class` | `internal` | Exactly C#. A class stays **source-portable** — it must lift into an external C# project verbatim, so its rules follow C#'s without deviation. |
| `component` | *(none)* | A component's access is governed by **authorization**, not visibility. See below. |

An explicit `public` or `internal` always overrides the default. `private` is not a top-level modifier — C# has
no private top-level types, and neither does Osy#.

### What visibility controls   {#controls}
Visibility is a **hard access rule**, not a decoration. An `internal` type cannot be named from outside its
namespace, and `using SomeNamespace;` brings only that namespace's **public** types into scope. This is how a
published unit distinguishes what it offers from what it merely uses.

Because an `entity` and an `enum` default to **public**, a unit that means to keep one to itself must say so:

```osy syntax
entity Product { … }             // exposed to anyone who imports this namespace
internal entity PriceHistory { … } // an implementation detail — say `internal` explicitly
```

### A component has no visibility   {#components}
Writing `public component` or `internal component` is an **error**. A component's reachability is decided on a
different axis — **authorization**: a routed component requires an authenticated caller unless it is marked
`[AllowAnonymous]`, and `[Composable]` governs whether it may be rendered inside another component's surface.
Type visibility would be a second, redundant gate answering a question authorization already answers, so a
component simply doesn't have one.

### Entity fields are always public   {#entity-fields}
A visibility modifier on an **entity field** is an error — the field *is* the data, so it is always public. A
`class` member is different: it carries its own [`public`/`private`](https://osysharp.com/reference/class/constructors/) **member**
visibility, and a bare member is `private`, exactly as in C#.

## Examples       {#examples}
```osy title="what each default is, and how to override it" test app=types-visibility
/// A catalog item other code may reference. `entity` is public by default.
entity Product {
  [Required] string Name;
  decimal Price;
}

/// An internal roll-up used only inside this namespace — say `internal` to keep it in.
internal entity PriceHistory {
  Product Item;
  decimal Was;
}

/// A class is internal by default (C#); mark it `public` to offer it outward.
public class Money {
  public decimal Amount;
  public string Currency;
}
```

## See also       {#see-also}
- [namespace](https://osysharp.com/reference/types/namespace/) — the namespace a type lives in, and what `internal` therefore keeps it inside of.
- [constructor](https://osysharp.com/reference/class/constructors/) — member visibility (`public`/`private`) on class members, the other visibility axis.
- [component](https://osysharp.com/reference/ui/component/) — why a component's access is an authorization question, not a visibility one.
