Core libraries and framework for building Workday Everywhere platform integrations.
mkdir my-plugin && cd my-plugin
npm init -y
npx @workday/everywhere init
npx @workday/everywhere viewThis creates a new plugin project, scaffolds a starter plugin.tsx, installs dependencies, and
opens a local dev preview at http://localhost:4242 with hot reloading.
Create a new directory for your Workday Everywhere plugin and scaffold it with the CLI:
mkdir my-plugin && cd my-plugin
npm init -y
npx @workday/everywhere initThe init command adds @workday/everywhere, react, and react-dom to your package.json,
creates a starter plugin.tsx, and runs npm install automatically.
The generated plugin.tsx defines your plugin's pages:
import { plugin } from '@workday/everywhere';
function HomePage() {
return (
<div style={{ padding: 16 }}>
<h1>Welcome to my-plugin!</h1>
<p>This is a simple plugin with a single page.</p>
</div>
);
}
export default plugin({
pages: [{ id: 'home', title: 'Home', component: HomePage }],
});Each page has an id, title, and React component. Add more pages to the pages array to create
multi-page plugins.
Launch the local dev server to preview your plugin in the browser:
npx @workday/everywhere viewThis starts a Vite dev server at http://localhost:4242 with hot reloading.
Package your plugin into a distributable zip file:
npx everywhere buildThis produces a dist/<name>-<version>.zip containing package.json, the bundled plugin.js, and
when present plugin.css plus any hashed static assets under assets/.
Plugins can connect directly to Workday's Trident GraphQL API to read and write data from Extend business objects.
Point everywhere bind at your downloaded Extend bundle directory (the folder containing the
model/ subfolder):
npx @workday/everywhere bind /path/to/your-bundleThis reads all .businessobject and .attachment model files and generates into
everywhere/data/:
models.ts— TypeScript interfaces for each modelschema.ts— Runtime schema used byTridentResolverto build GraphQL queries<ModelName>.ts—useModelName(),useModelName(id), anduseModelNameMutation()hooks
Generated types reflect the full model: scalar fields, SINGLE_INSTANCE / MULTI_INSTANCE
references, derived fields (marked readonly), and CurrencyValue for CURRENCY fields.
Note: Run
bindagain whenever you update the bundle. The output directory is saved so you can re-run with justnpx @workday/everywhere bind.
TridentResolver translates hook calls into Trident GraphQL requests. Add it to your plugin.tsx:
import { plugin, DataProvider, TridentResolver } from '@workday/everywhere';
import { CanvasProvider } from '@workday/canvas-kit-react';
import { schemas } from './everywhere/data/schema.js';
// The referenceId comes from appManifest.json in your bundle.
const TRIDENT_ENDPOINT = 'https://api.us.wcp.workday.com';
const TRIDENT_PATH = '/graphql/v5';
const BEARER_TOKEN = 'YOUR_BEARER_TOKEN'; // replace before running
const resolver = new TridentResolver(
TRIDENT_ENDPOINT,
TRIDENT_PATH,
BEARER_TOKEN,
'YourAppReferenceId', // replace before running, found in manifest.json in the app bundle
schemas
);
function AppProvider({ children }) {
return (
<CanvasProvider>
<DataProvider resolver={resolver}>{children}</DataProvider>
</CanvasProvider>
);
}
export default plugin({
provider: AppProvider,
pages: [ ... ],
});Bearer token: Tokens expire. When a request fails due to auth, the error message will tell you to update
BEARER_TOKEN.
The generated hooks work like useSWR — they fetch on mount and return { data, error }:
import { useWorkEvents } from '../everywhere/data/WorkEvent.js';
export default function EventListPage() {
const { data: events, error } = useWorkEvents();
if (error) return <Text color="cinnamon500">{error.message}</Text>;
return (
<>{Array.isArray(events) && events.map((event) => <div key={event.id}>{event.name}</div>)}</>
);
}data is null while loading and an array once resolved. Check Array.isArray(data) before
rendering to distinguish loading from empty.
React hooks rule: Call all hooks (including
useMemo) before any earlyreturn. Returning early before a hook call causes a "Rendered fewer hooks than expected" crash.
All commands accept -D <path> to specify the plugin directory (defaults to the current working
directory).
| Command | Description |
|---|---|
everywhere init |
Scaffold a new plugin in an existing project |
everywhere view |
Preview a plugin in the browser |
everywhere build |
Bundle and package a plugin into a zip file |
everywhere publish |
Build and publish a plugin to the Workday registry |
everywhere install |
Build and install a plugin to a local directory |
everywhere info |
Show plugin details from package.json |
everywhere bind |
Generate TypeScript types from Extend models |
everywhere auth |
Manage authentication with Workday servers |
- Use
@workday/everywhere(and@workday/everywhere/dataor@workday/everywhere/hooks) for plugin runtime code. - Treat CLI modules under
cli/src/**as internal implementation details. @workday/everywhere/buildis a deprecated compatibility surface; prefer CLI commands such aseverywhere build.
See docs/cli-sdk-boundary.md for the boundary policy and deprecation
direction.
See CONTRIBUTING.md for development setup and guidelines.