Portable Node Format V1.0.0
Technical Documentation for .node
Deep dive into the architecture, implementation, and technical specifications of the Node File Link addon.
This documentation covers the internal workings of the .node file format, serialization engine, and Blender integration mechanisms that power seamless node group sharing and distribution.
- Advanced Serialization: Complete node tree serialization with metadata, properties, and interface definitions
- Cross-Version Compatibility: Handles Blender 4.1+ interface changes and node tree variations
- Windows Registry Integration: Automatic file association registration with custom icon support
- Real-time Import System: Drag & drop functionality with cursor-aware node placement
Deep dive into the architecture, implementation, and technical specifications of the Node File Link addon.
folder_openFile Format Specification
Internal Structure
A .node file is a ZIP archive containing exactly three components:
| Component | Filename | Purpose | Format |
| Metadata | {package_name}.json | Node structure, properties, and interface definitions | JSON with UTF-8 encoding |
| Node Data | {package_name}.blend | Actual Blender node group data for importing | Standard Blender file |
| Package Config | .config | Package validation and integrity verification | Plain text key=value pairs |
JSON Metadata Schema
The JSON metadata follows a structured schema that captures complete node tree information:
{ "nodegroup_info": { "name": "string", // Original node group name "package_name": "string", // Sanitized package identifier "description": "string", // Node group description "type": "GeometryNodeTree", // Blender node tree type "version": "1.0.0", // Package format version "blender_version": "string", // Source Blender version "export_timestamp": "ISO8601" // Creation timestamp }, "interface": { "inputs": [...], // Input socket definitions "outputs": [...] // Output socket definitions }, "nodes": [...], // Individual node data "links": [...], // Node connections "layout": { // Visual layout information "frames": [...], // Frame node data "reroutes": [...] // Reroute node positions }, "dependencies": { // External dependencies "node_groups": [...], // Required node groups "materials": [...], // Material dependencies "objects": [...], // Object references "images": [...], // Image textures "texts": [...] // Text datablocks }} Socket Serialization
Socket data includes comprehensive type information and default values:
{ "name": "string", "identifier": "string", // Unique socket identifier "socket_type": "string", // Blender socket type (bl_idname) "in_out": "INPUT|OUTPUT", // Socket direction "description": "string", // User description "default_value": "variant", // Serialized default value "min_value": "number", // Optional range constraints "max_value": "number", "subtype": "string", // Socket subtype information "attribute_domain": "string" // Geometry domain (4.5+)} Package Validation System
The .config file contains integrity verification data:
hash=sha256_hash_of_all_filescreated=2025-09-07T12:34:56Zformat_version=1.0.0 The hash is computed from all file contents in the package, ensuring data integrity during transfer and storage.
settingsSerialization Engine
NodeGroupSerializer Class
The serialization engine handles the complex task of converting Blender's internal node tree representation into a portable format:
Core Serialization Methods
| Method | Purpose | Output |
_serialize_interface() | Extract input/output socket definitions | Interface structure with socket metadata |
_serialize_nodes() | Capture individual node properties and settings | Complete node data with properties |
_serialize_links() | Map all node connections and relationships | Connection data with socket identifiers |
_serialize_layout() | Preserve visual arrangement (frames, reroutes) | Layout positioning information |
Blender Version Compatibility
The serializer handles interface differences between Blender versions:
// Blender 4.5+ Interface APIif hasattr(self.node_group, 'interface') and hasattr(self.node_group.interface, 'items_tree'): for item in self.node_group.interface.items_tree: if hasattr(item, 'item_type') and item.item_type == 'SOCKET': // Process modern interface structure // Fallback for Blender 4.1-4.4elif hasattr(self.node_group, 'inputs') and hasattr(self.node_group, 'outputs'): for input_socket in self.node_group.inputs: // Process legacy interface structure Advanced Property Handling
The serializer captures node-specific properties including:
-
Mathematical Properties:
operation,blend_type,distribution,mode -
Data Properties:
data_type,domain,interpolation,resolution -
Control Properties:
use_clamp,clamp_factor,offset,scale -
Custom Properties: User-defined properties via
node.keys()
Default Value Serialization
Complex data types are handled with appropriate serialization:
def _serialize_socket_default_value(self, socket): if not hasattr(socket, 'default_value'): return None try: value = socket.default_value # Handle Blender math types if hasattr(value, '__iter__') and not isinstance(value, str): return list(value) # Vector, Color, Euler elif hasattr(value, 'copy'): return value.copy() # Ensure immutable copy else: return value # Primitive types except Exception: return None # Fallback for unsupported types inputImport & Unpacking System
NodeGroupUnpacker Class
The unpacking system reconstructs Blender node trees from .node files with full fidelity:
Import Process Flow
- File Validation - Verify ZIP structure and required components
- Integrity Check - Validate package hash against contents
- Temporary Extraction - Extract to secure temporary directory
- Blend File Import - Use Blender's append system for node data
- Context Placement - Place nodes at cursor or default location
- Cleanup - Remove temporary files and update UI
Multi-File Processing
The unpacker supports batch processing of multiple .node files:
def process_multiple_files(self, file_paths): success_count = 0 error_count = 0 error_messages = [] for file_path in file_paths: success, message = self.unpack_node_file(file_path) if success: success_count += 1 else: error_count += 1 error_messages.append(message) return success_count, error_count, error_messages Context-Aware Node Placement
The system intelligently places imported nodes based on context:
| Context | Placement Strategy | Behavior |
| Single File Import | Cursor Position | Place at exact mouse coordinates |
| Multiple File Import | Default Location | Place at node editor origin |
| Background Import | Context-Sensitive | Place based on active editor space |
desktop_windowsWindows Integration
File Association System
The FileAssociationManager class handles Windows registry integration for seamless file handling:
Registry Structure
The addon creates the following registry entries:
HKEY_CURRENT_USER\Software\Classes\.node └── (Default) = "NodeFile"HKEY_CURRENT_USER\Software\Classes\NodeFile ├── (Default) = "Node Archive File" ├── DefaultIcon │ └── (Default) = "C:\path\to\addon\icons\logo_xwz_ne.ico" └── shell\open\command └── (Default) = "C:\Program Files\7-Zip\7zFM.exe \"%1\"" Archive Application Discovery
The system automatically detects suitable archive applications:
- 7-Zip Detection - Check standard installation paths and PATH environment
- Registry Lookup - Query both 32-bit and 64-bit registry entries
- WinRAR Fallback - Detect WinRAR installations if 7-Zip unavailable
- System Default - Use Windows "Open With" dialog as last resort
Shell Integration Features
-
Custom Icons:
.nodefiles display with custom XWZ icon - Context Menu: Right-click integration for "Open with Archive Manager"
- Double-Click Handling: Direct access to file contents via archive viewer
- Shell Notifications: Automatic icon cache refresh and file association updates
drag_handleDrag & Drop System
Drop Handler Implementation
The drag & drop system uses Blender's FileHandler API for seamless integration:
class NODE_FH_drop_handler(bpy.types.FileHandler): bl_idname = "NODE_FH_drop_handler" bl_label = "Node Drop Handler" bl_import_operator = "node.drop_handler" bl_file_extensions = ".node" @classmethod def poll_drop(cls, context): return True // Accept drops in any context Mouse Coordinate Capture
Precise cursor positioning for intelligent node placement:
def invoke(self, context, event): self.mouse_x = event.mouse_region_x if hasattr(event, 'mouse_region_x') else 0 self.mouse_y = event.mouse_region_y if hasattr(event, 'mouse_region_y') else 0 // Pass coordinates to unpacker for placement Multi-File Batch Processing
The handler efficiently processes multiple files dropped simultaneously:
Processing Pipeline
-
File Validation - Filter
.nodefiles from mixed drops - Path Resolution - Convert relative paths to absolute paths
- Batch Processing - Process all valid files in sequence
- Error Aggregation - Collect and report processing results
- UI Feedback - Provide detailed success/failure notifications
tuneConfiguration & Settings
Addon Manifest Configuration
schema_version = "1.0.0"id = "node_file_link"name = "Node File Link"tagline = "The base functionality for the .node extension"version = "1.0.0"type = "add-on"maintainer = "XWZ"website = "https://xwz.app"license = ["MIT"]blender_version_min = "4.1.0" Package Creation System
The package.bat script creates optimized .node files with integrity verification:
PowerShell Integration
Uses .NET compression APIs for cross-platform compatibility:
Add-Type -AssemblyName System.IO.Compression.FileSystem$zip = [System.IO.Compression.ZipFile]::Open('output.node', 'Create')// Add files with proper directory structure// Calculate SHA256 hash for integrity// Create .config file with validation data// Create .config file with validation data Hash Calculation Algorithm
- Calculate SHA256 hash for each file in package
- Sort hashes alphabetically for consistency
- Combine all hashes with pipe separator
- Calculate final SHA256 hash of combined string
- Store in
.configfile for validation
apiAPI Reference
Core Classes
NodeGroupSerializer
| Method | Parameters | Returns |
serialize_nodegroup() | node_tree, output_directory, package_name |
bool (success status) |
_create_metadata_json() | None |
bool (creation success) |
_create_blend_file() | None |
bool (export success) |
NodeGroupUnpacker
| Method | Parameters | Returns |
unpack_node_file() | filepath: str |
Tuple[bool, str] (success, message) |
process_multiple_files() | file_paths: List[str] |
Tuple[int, int, List[str]] (success_count, error_count, errors) |
_validate_package() | package_path: str |
bool (validation success) |
set_mouse_coordinates() x: int, y: int None FileAssociationManager
| Method | Parameters | Returns |
perform_file_association() | None |
bool (registration success) |
find_archive_application() | None |
str (application path) |
check_existing_association() | None |
str | None (existing ProgID) |
codeDevelopment Guidelines
Extending the System
For developers looking to extend or modify the addon:
-
Custom Serializers: Inherit from
NodeGroupSerializerfor specialized node types - Additional File Formats: Implement new packers/unpackers following the established pattern
- Platform Support: Add file association managers for macOS and Linux
- UI Extensions: Integrate additional operators into Blender's interface
analyticsTechnical Specifications
| Specification | Value | Notes |
| File Format Version | 1.0.0 | Current format specification |
| Supported Node Types | GeometryNodeTree | Primary focus on Geometry Nodes |
| Blender Compatibility | 4.1.0+ | Modern extension system required |
| Platform Support | Windows | macOS and Linux support planned |
| Maximum File Size | Unlimited | Limited by available system memory |
| Compression | ZIP (deflate) | Standard compression for portability |
| Hash Algorithm | SHA256 | Cryptographic integrity verification |
| Character Encoding | UTF-8 | Universal text encoding support |
historyChangelog
- Version 1.0.0 (September 2025): Initial release with core functionality