# Using Namespaces

Learn how to organize exported Swift code into JavaScript namespaces.

## Overview

> Tip: You can quickly preview what interfaces will be exposed on the Swift/JavaScript/TypeScript sides using the [BridgeJS Playground](https://swiftwasm.org/JavaScriptKit/PlayBridgeJS/).

The `@JS` macro supports organizing your exported Swift code into namespaces using dot-separated strings. This allows you to create hierarchical structures in JavaScript that mirror your Swift code organization.

There are two ways to create namespaces:
1. **`@JS(namespace:)`** - Explicitly specify a namespace for functions, classes, or enums
2. **Namespace enums** - Use empty enums to create implicit namespace hierarchies (see <doc:Exporting-Swift-Enum>)

## Functions with Namespaces

You can export functions to specific namespaces by providing a namespace parameter:

```swift
import JavaScriptKit

// Export a function to a custom namespace
@JS(namespace: "MyModule.Utils") func namespacedFunction() -> String {
    return "namespaced"
}
```

This function will be accessible in JavaScript through its namespace hierarchy in two ways:

```javascript
// Recommended: Access via the exports object (supports multiple WASM instances)
const { createInstantiator } = await import('./path/to/bridge-js.js');
const instantiator = await createInstantiator(options, swift);
const exports = instantiator.createExports(instance);

const result = exports.MyModule.Utils.namespacedFunction();
console.log(result); // "namespaced"

// Alternative: Access via globalThis
const result = globalThis.MyModule.Utils.namespacedFunction();
console.log(result); // "namespaced"
```

The generated TypeScript declaration will reflect the namespace structure:

```typescript
declare global {
    namespace MyModule {
        namespace Utils {
            function namespacedFunction(): string;
        }
    }
}
```

## Classes with Namespaces

For classes, you only need to specify the namespace on the top-level class declaration. All exported methods within the class will be part of that namespace:

```swift
import JavaScriptKit

@JS(namespace: "__Swift.Foundation") class Greeter {
    var name: String

    @JS init(name: String) {
        self.name = name
    }

    @JS func greet() -> String {
        return "Hello, " + self.name + "!"
    }

    func changeName(name: String) {
        self.name = name
    }
}
```

In JavaScript, this class is accessible through its namespace:

```javascript
// Always available: Access via the exports object (supports multiple WASM instances)
const greeter = new exports.__Swift.Foundation.Greeter("World");
console.log(greeter.greet()); // "Hello, World!"

// When exposeToGlobal: true - Also available via globalThis
const greeter = new globalThis.__Swift.Foundation.Greeter("World");
console.log(greeter.greet()); // "Hello, World!"
```

> Note: Global namespace access via `globalThis` is only available when `exposeToGlobal: true` is set in your `bridge-js.config.json`. See <doc:BridgeJS-Configuration> for more details.

The generated TypeScript declaration will organize the class within its namespace:

```typescript
declare global {
    namespace __Swift {
        namespace Foundation {
            class Greeter {
                constructor(name: string);
                greet(): string;
            }
        }
    }
}

export type Exports = {
    __Swift: {
        Foundation: {
            Greeter: {
                new(name: string): Greeter;
            }
        }
    }
}

export interface Greeter extends SwiftHeapObject {
    greet(): string;
}
```

Using namespaces can be preferable for projects with many global functions, as they help prevent naming collisions. Namespaces also provide intuitive hierarchies for organizing your exported Swift code, and they do not affect the code generated by `@JS` declarations without namespaces.
