> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/nvaccess/nvda/llms.txt
> Use this file to discover all available pages before exploring further.

# Architecture Overview

> Understanding NVDA's core architecture and design patterns

NVDA's architecture is built around several key design patterns that work together to provide screen reading functionality across different applications and accessibility APIs.

## Core Components

NVDA's architecture consists of several interconnected components:

<CardGroup cols={2}>
  <Card title="NVDA Objects" icon="cube" href="/development/architecture/nvda-objects">
    Representations of GUI controls and widgets
  </Card>

  <Card title="Events" icon="bolt" href="/development/architecture/events">
    System for handling accessibility events
  </Card>

  <Card title="Scripts & Gestures" icon="keyboard" href="/development/architecture/scripts-and-gestures">
    Input handling and command binding
  </Card>

  <Card title="Plugins" icon="puzzle-piece" href="/development/plugins">
    App modules and global plugins
  </Card>
</CardGroup>

## Architecture Layers

### 1. API Layer

NVDA supports multiple accessibility APIs through specialized classes:

* **IAccessible/MSAA**: Windows legacy accessibility API
* **IAccessible2**: Extended accessibility interface
* **UI Automation (UIA)**: Modern Windows accessibility API
* **Java Access Bridge (JAB)**: Java application support
* **Window**: Direct Win32 window support

These API classes are located in `source/NVDAObjects/` with subdirectories for each API.

### 2. Object Layer

All GUI elements are represented as NVDA Objects, which provide:

* Standardized properties (name, role, value, states)
* Navigation (parent, children, next, previous)
* Event handling
* Text access through TextInfo objects

### 3. Plugin Layer

Plugins customize NVDA's behavior through:

* **App Modules**: Application-specific functionality
* **Global Plugins**: System-wide features
* **Overlay Classes**: Custom NVDA Object behaviors

## Base Object System

NVDA uses a sophisticated base object system defined in `baseObject.py`:

### AutoPropertyObject

Provides automatic property generation from getter/setter methods:

```python theme={null}
class MyObject(AutoPropertyObject):
    def _get_name(self):
        return "My Name"
    
    def _set_name(self, value):
        self._name = value
    
    # Properties can be cached
    _cache_expensiveValue = True
    
    def _get_expensiveValue(self):
        # This result will be cached for one core pump cycle
        return self._calculateExpensiveValue()
```

<Note>
  Setting `cachePropertiesByDefault = True` on a class caches all properties by default. Individual properties can override this with `_cache_propertyName = True/False`.
</Note>

### ScriptableObject

Provides script and gesture binding capabilities:

```python theme={null}
class MyScriptable(ScriptableObject):
    # Define gestures in a dictionary
    __gestures = {
        "kb:NVDA+shift+t": "sayTime",
        "kb:NVDA+shift+d": "sayDate",
    }
    
    def script_sayTime(self, gesture):
        """Reports the current time"""
        import datetime
        ui.message(str(datetime.datetime.now().time()))
    
    def script_sayDate(self, gesture):
        """Reports the current date"""
        import datetime
        ui.message(str(datetime.datetime.now().date()))
```

## Dynamic Class Creation

One of NVDA's most powerful features is dynamic class creation. When an NVDA Object is created, it:

1. **Determines the API class** (IAccessible, UIA, etc.)
2. **Finds overlay classes** through `findOverlayClasses()`
3. **Allows plugins to add classes** via `chooseNVDAObjectOverlayClasses()`
4. **Constructs a dynamic class** combining all chosen classes
5. **Initializes overlay classes** by calling `initOverlayClass()` on each

```python theme={null}
# Example from DynamicNVDAObjectType.__call__
clsList = []
obj.findOverlayClasses(clsList)  # API-level classes
appModule.chooseNVDAObjectOverlayClasses(obj, clsList)  # App module classes

# Construct dynamic class from bases
bases = tuple(optimized_class_list)
name = "Dynamic_" + "_".join([x.__name__ for x in clsList])
newCls = type(name, bases, {"__module__": __name__})

# Mutate object into new class
obj.__class__ = newCls
```

<Tip>
  This pattern allows NVDA to create highly specialized objects that combine generic API support with application-specific behavior without modifying the core codebase.
</Tip>

## Event Flow

When an accessibility event occurs:

1. **OS/API fires event** (e.g., focus change)
2. **NVDA receives event** through API monitoring
3. **Event propagates** through handler chain:
   * Global Plugins
   * App Module
   * Tree Interceptor (if applicable)
   * NVDA Object itself
4. **Handler processes** or calls `nextHandler()` to continue

```python theme={null}
# In a Global Plugin
def event_gainFocus(self, obj, nextHandler):
    # Do custom processing
    log.info(f"Focus changed to: {obj.name}")
    # Propagate to next handler
    nextHandler()
```

## Script Resolution

When a user presses a key:

1. **Input captured** by NVDA
2. **Gesture normalized** to identifier (e.g., "kb:NVDA+t")
3. **Script search** in priority order:
   * User gesture map
   * Locale gesture map
   * Braille display driver gestures
   * Global Plugins
   * App Module
   * Tree Interceptor
   * NVDA Object with focus
   * Focus ancestors (if script has `canPropagate=True`)
   * Global Commands
4. **Script executed** if found

```python theme={null}
# Script resolution order from scriptHandler.py
def _yieldObjectsForFindScript(gesture):
    yield gesture.scriptableObject
    yield from globalPluginHandler.runningPlugins
    yield focus.appModule
    yield braille.handler.display
    yield treeInterceptor
    yield focus
    yield from reversed(api.getFocusAncestors())
    yield globalCommands.commands
```

## Text Access

NVDA provides text access through the TextInfo system:

* **NVDAObjectTextInfo**: Default implementation for object properties
* **DisplayModelTextInfo**: Screen scraping fallback
* **Specialized TextInfo classes**: For editable text, documents, etc.

TextInfo objects support:

* Unit-based movement (character, word, line, paragraph)
* Text extraction and formatting info
* Bounding rectangles for screen location
* Bookmarking and comparison

## Memory Management

NVDA uses several techniques for efficient memory management:

* **Weak references**: For cached objects like app modules and tree interceptors
* **Garbage collection tracking**: Through `garbageHandler.TrackedObject`
* **Cache invalidation**: Properties cached only for one core pump cycle
* **Dynamic class caching**: Reuses dynamically created classes

```python theme={null}
class AutoPropertyObject(garbageHandler.TrackedObject):
    __instances = weakref.WeakKeyDictionary()
    
    @classmethod
    def invalidateCaches(cls):
        """Invalidate all instance caches"""
        for instance in list(cls.__instances):
            instance.invalidateCache()
```

## Threading Model

NVDA uses a main thread for most operations with:

* **Queue handler**: For sequencing operations
* **Event queue**: For processing events in order
* **Script execution**: Synchronous on main thread
* **Speech/braille**: Queued for output

<Warning>
  Most NVDA operations must run on the main thread. Use `queueHandler.queueFunction()` to safely queue operations from background threads.
</Warning>

## Configuration System

NVDA's configuration follows a layered approach:

* **Default config**: Built-in defaults
* **User config**: User's configuration directory
* **Configuration profiles**: Context-specific settings
* **Scratchpad**: Developer testing area

## Next Steps

<CardGroup cols={2}>
  <Card title="NVDA Objects" icon="cube" href="/development/architecture/nvda-objects">
    Deep dive into NVDA Object system
  </Card>

  <Card title="Events" icon="bolt" href="/development/architecture/events">
    Learn about event handling
  </Card>

  <Card title="Scripts & Gestures" icon="keyboard" href="/development/architecture/scripts-and-gestures">
    Master input handling
  </Card>

  <Card title="Writing Plugins" icon="code" href="/development/plugins">
    Create your first plugin
  </Card>
</CardGroup>
