Plugin Development Overview
Learn how to build powerful plugins for the CNC application. This guide covers everything from basic concepts to advanced features.
Prerequisites
Before you start developing plugins, ensure you have:
- Node.js 18+ installed
- TypeScript knowledge
- React 18+ experience
- Basic understanding of CNC/machining concepts
Quick Start
1. Clone Plugin Template
git clone https://github.com/whttlr/plugin-template my-plugin
cd my-plugin
npm install
2. Update Plugin Manifest
package.json
{
"name": "my-plugin",
"version": "1.0.0",
"cncPlugin": {
"apiVersion": "1.0.0",
"displayName": "My Plugin",
"placement": "dashboard"
}
}
3. Start Development
npm run dev # Start development server
npm run build # Build for production
npm run test # Run tests
Plugin Architecture
Core Components
CNC Application
├── PluginContext Service # Plugin lifecycle management
├── PluginRenderer # UI rendering system
├── PluginAPI # Data access interface
├── Database Integration # State persistence
└── Configuration System # Settings management
Plugin Structure
my-plugin/
├── package.json # Plugin manifest and dependencies
├── src/
│ ├── index.tsx # Main plugin entry point
│ ├── components/ # React components
│ ├── services/ # Plugin-specific services
│ └── types/ # TypeScript type definitions
├── assets/ # Static resources (images, icons)
├── tests/ # Unit and integration tests
└── README.md # Plugin documentation
Plugin Types
Dashboard Plugin
Perfect for status monitoring and quick controls.
src/DashboardWidget.tsx
import React from 'react';
import { PluginAPI } from '@cnc/plugin-api';
const DashboardWidget: React.FC<{ api: PluginAPI }> = ({ api }) => {
const jogSpeed = api.config.get('jog.speed.xy');
return (
<div className="plugin-card">
<h4>Jog Speed Monitor</h4>
<p>Current: {jogSpeed} mm/min</p>
</div>
);
};
export default DashboardWidget;
Manifest Configuration
{
"cncPlugin": {
"placement": "dashboard",
"size": { "width": 400, "height": 300 },
"permissions": ["machine.read"]
}
}
Standalone Application
Full-screen applications with dedicated functionality.
src/StandaloneApp.tsx
import React from 'react';
import { PluginAPI } from '@cnc/plugin-api';
const StandaloneApp: React.FC<{ api: PluginAPI }> = ({ api }) => {
return (
<div className="plugin-app">
<h1>My CNC Tool</h1>
<p>Full application interface here</p>
</div>
);
};
export default StandaloneApp;
Manifest Configuration
{
"cncPlugin": {
"placement": "standalone",
"menuTitle": "My Tool",
"menuIcon": "ToolOutlined",
"routePath": "/my-tool"
}
}
Development Workflow
1. Setup Development Environment
# Create new plugin
npm run create-plugin my-widget "My Widget" dashboard
# Install dependencies
cd my-widget
npm install
# Start development
npm run dev
2. Plugin Development Loop
- Write Tests (TDD approach)
- Implement Features
- Test in Application
- Refine and Iterate
3. Testing
tests/MyPlugin.test.tsx
import { render, screen } from '@testing-library/react';
import MyPlugin from '../src/MyPlugin';
import { mockPluginAPI } from '@cnc/test-utils';
test('renders plugin correctly', () => {
const api = mockPluginAPI({
config: { 'jog.speed.xy': 1000 }
});
render(<MyPlugin api={api} />);
expect(screen.getByText('Current: 1000')).toBeInTheDocument();
});
4. Building and Packaging
# Build for production
npm run build
# Create distribution package
npm run package
# Validate plugin
npm run validate
Key Development Concepts
Plugin API Access
interface PluginAPI {
config: ConfigAPI; // Configuration access
machine: MachineAPI; // Machine data (planned)
events: EventAPI; // Event system (planned)
storage: StorageAPI; // Plugin storage (planned)
ui: UIAPI; // UI utilities (planned)
}
Configuration Access
// Access machine settings
const units = api.config.get('machine.units');
const homePosition = api.config.get('machine.home');
// Get configuration sections
const jogSettings = api.config.getSection('jog');
// With fallback values
const customValue = api.config.getWithFallback('my.setting', 'default');
Permission System
Declare required permissions in your manifest:
{
"cncPlugin": {
"permissions": [
"machine.read", // Read machine status
"config.read", // Read configuration
"network.access" // External API calls
]
}
}
Best Practices
Code Quality
- ✅ Use TypeScript for better type safety
- ✅ Follow React patterns and hooks
- ✅ Implement proper error handling
- ✅ Write comprehensive tests
Security
- ✅ Request minimal permissions
- ✅ Validate all user inputs
- ✅ Use provided APIs instead of direct access
- ✅ Sanitize dynamic content
Performance
- ✅ Keep bundle size minimal
- ✅ Implement proper cleanup
- ✅ Use lazy loading when appropriate
- ✅ Optimize re-renders
UI/UX
- ✅ Follow application theme
- ✅ Support responsive layouts
- ✅ Provide loading states
- ✅ Use Ant Design components
Next Steps
Now that you understand the basics, you can:
- Expand your plugin with more advanced features
- Test thoroughly before publishing
- Follow React best practices for UI components
- Use TypeScript for better development experience
Ready to share your plugin? Check the quick reference for publishing information and command references!