Teaching AI coding assistants Oracle APEX

How to utilize SKILL.md files to teach AI coding assistants like Claude Code about how to use Oracle APEX-specific concepts.

The problem of working with niche technologies

If you ask AI to create a website, it will do an excellent job and most likely utilize React and Tailwind CSS. These technologies are open source, widely used (many GitHub projects), and well documented. So the AI is heavily trained on them and can work with them fluently.

Oracle is different. Closed source, niche, and not much public code on the internet. It’s still great to see how well Claude performs in creating PL/SQL packages, but we probably all have seen AI hallucinating some kind of APEX API package that doesn’t exist. So instead we have to teach the AI about APEX concepts and APIs.

Teaching AI about APEX through context

This issue might sound familiar. We can solve it by just giving the AI context about our technology stack. If we give AI the right context, it can use that information instead of making things up.

But the issue is that context is a balancing act. Not enough context and the AI will hallucinate; too much context and the AI will be expensive, slow, and – most importantly – perform worse.

The answer is to give just enough context needed to solve the current issue. Instead of always teaching all APEX APIs, icons, views, etc., we only give Template Component context when the task is Template Component related. This is essentially a search problem; we need to find and surface only the relevant information. This concept is called Retrieval Augmented Generation (RAG).

For our coding agents, there is an emerging spec that makes it easy to give ad hoc context called SKILL.md.

So we could create a SKILL.md file for APEX Template Components and in that teach how they work and how the AI can assist us in creating one for us. When we ask about Template Components the LLM will see that there is a matching SKILL.md file available (ignoring any irrelevant ones), read it, and use the information to provide accurate and relevant results.

AI, create me a template component

So as I use Claude Code, I just created a .claude/skills/template-components/SKILL.md file. In it I carefully wrote down all the relevant (basic) information that will help Claude to create helpful ones. Then I let Claude refine this file for clarity and conciseness, since context should be as clear as possible for LLMs to use effectively.

---
name: template-component
description: Create a template component for Oracle APEX applications
---

Generate an Oracle APEX Template Component based on user description. Write files to `src/template-components/<component-name>/`.

## Output Files

Create these files in `src/template-components/<component-name>/`:

| File                    | Required | Description                                                                             |
| ----------------------- | -------- | --------------------------------------------------------------------------------------- |
| `partial.html`          | Yes      | Renders individual row data with `#COLUMN_NAME#` substitutions                          |
| `report-row.html`       | Yes      | Wrapper for each partial (default: `<li #APEX$ROW_IDENTIFICATION#>#APEX$PARTIAL#</li>`) |
| `report-body.html`      | Yes      | Wrapper for all rows (default: `<ul>#APEX$ROWS#</ul>`)                                  |
| `report-container.html` | No       | Outer wrapper using `#APEX$REPORT_BODY#` and `#APEX$DOM_ID#`                            |
| `index.css`             | No       | Component styles                                                                        |
| `index.js`              | No       | Client-side interactivity using APEX APIs                                               |
| `README.md`             | Yes      | Setup instructions and sample query                                                     |

## APEX Template Substitution Syntax

**Column values:** `#COLUMN_NAME#` → replaced by query column value

**Conditionals:**

```html
{case STATUS/}{when ACTIVE/}green{when INACTIVE/}gray{otherwise/}blue{endcase/}
{if IS_VISIBLE/}Show this{else/}Hide this{endif/}
```

**Loops (for JSON arrays):**

```html
{loop "," TAGS/}<span class="tag">&APEX$ITEM.</span>{endloop/}
```

**Built-in placeholders:**

- `#APEX$PARTIAL#` - inserts partial template
- `#APEX$ROWS#` - inserts all report rows
- `#APEX$ROW_IDENTIFICATION#` - row CSS ID/class for selection
- `#APEX$REPORT_BODY#` - inserts report body
- `#APEX$DOM_ID#` - unique component DOM ID

## Required User Input

Ask the user for:

1. **Component name** (kebab-case for directory, e.g., "employee-cards")
2. **Query columns** with types (e.g., `EMP_ID NUMBER, NAME VARCHAR2, SKILLS JSON_ARRAY`)
3. **Visual description** of the component layout

## Defaults

- Use APEX utility classes
- Include ARIA attributes for accessibility
- Use `rem`/`em` units in CSS
- Template components should take up the whole width of their container by default

Making them look like APEX

The results are excellent, and I would have spent a lot of time to create something like that myself. But they do not look like APEX components. Again, remember that AI is trained on plenty of projects but not much on APEX projects. If you want your app to look cohesive rather than like a patchwork of different styles, you also need to teach your AI about APEX utility classes and CSS variables.

I remembered that I have a project for Alfred (macOS Spotlight search) that lets me look up information quickly. I can hit CMD+Space, type apex css variables primary and get filtered results like --ut-palette-primary or --ut-palette-primary-contrast (More on that project here). AI should know that as well. So we just create more SKILL.md files with the relevant information. When I asked Claude Code to make the template component look more APEX native, it did an outstanding job by utilizing the utility classes and CSS variables I taught it in the SKILL.md files.

apex-css-vars/SKILL.md

Display CSS variables SKILL.md
---
name: apex-css-vars
description: Returns Oracle APEX CSS custom properties (variables) for styling components
---

When asked about APEX CSS variables or when styling APEX components, return the relevant CSS variables from the data below.

## Usage

Use these CSS variables with `var(--variable-name)` in your CSS. For example:

```css
.my-component {
  background-color: var(--ut-component-background-color);
  color: var(--ut-component-text-default-color);
  border-radius: var(--ut-component-border-radius);
}
```

## Available CSS Variables

```
cssVars[51]{name,description}:
  u-color-1,Color palette #1 (up to 45)
  u-color-2,Color palette #2 (up to 45)
  u-color-3,Color palette #3 (up to 45)
  u-color-1-contrast,Color palette #1 contrast (up to 45)
  u-color-2-contrast,Color palette #2 contrast (up to 45)
  u-color-3-contrast,Color palette #3 contrast (up to 45)
  ut-palette-primary,Primary color in the palette
  ut-palette-primary-contrast,Contrast color for primary palette color
  ut-palette-primary-shade,Shade of the primary palette color
  ut-palette-primary-text,Text color of the primary palette that is readable on the shade
  ut-palette-danger,Danger color in the palette
  ut-palette-danger-contrast,Contrast color for danger palette color
  ut-palette-danger-shade,Shade of the danger palette color
  ut-palette-danger-text,Text color of the danger palette that is readable on the shade
  ut-palette-warning,Warning color in the palette
  ut-palette-warning-contrast,Contrast color for warning palette color
  ut-palette-warning-shade,Shade of the warning palette color
  ut-palette-warning-text,Text color of the warning palette that is readable on the shade
  ut-palette-success,Success color in the palette
  ut-palette-success-contrast,Contrast color for success palette color
  ut-palette-success-shade,Shade of the success palette color
  ut-palette-success-text,Text color of the success palette that is readable on the shade
  ut-palette-info,Info color in the palette
  ut-palette-info-contrast,Contrast color for info palette color
  ut-palette-info-shade,Shade of the info palette color
  ut-palette-info-text,Text color of the info palette that is readable on the shade
  ut-component-background-color,Component Background Color
  ut-component-border-color,Component Border Color
  ut-component-border-width,Component Border Width
  ut-component-border-radius,Component Border Radius
  ut-component-box-shadow,Component Shadow
  ut-component-highlight-background-color,Component Highlight Background Color (example: hover state)
  ut-component-toolbar-background-color,Component Toolbar Background Color
  ut-component-inner-border-width,Component Inner Border Width
  ut-component-inner-border-color,Component Inner Border Color
  ut-component-text-default-color,Component Default Text Color
  ut-component-text-title-color,Component Default Title Color
  ut-component-text-subtitle-color,Component Default Subtitle Color
  ut-component-text-muted-color,Component Default Muted Color (example: description text)
  ut-component-icon-background-color,Component Icon Background Color
  ut-component-icon-color,Component Icon Color
  ut-component-badge-background-color,Component Badge Background Color
  ut-component-badge-text-color,Component Badge Text Color
  ut-component-badge-border-radius,Component Badge Border Radius
  ut-shadow-sm,Shadow Small
  ut-shadow-md,Shadow Medium
  ut-shadow-lg,Shadow Large
  a-base-font-family,Base Font Family
  a-base-font-family-serif,Serif Base Font Family
  a-base-font-family-mono,Monospace Base Font Family
  ut-hero-region-title-font-family,Hero Region Title Font Family
```

## Categories

### Color Palette

Variables starting with `u-color-` provide numbered colors (1-45) with matching contrast colors.

### Semantic Colors

Variables with `ut-palette-` prefix provide semantic colors:

- **primary** - Main brand/action color
- **danger** - Error/destructive actions
- **warning** - Caution/attention
- **success** - Positive/confirmation
- **info** - Informational

Each semantic color has variants: base, `-contrast`, `-shade`, and `-text`.

### Component Styles

Variables with `ut-component-` prefix control component appearance including backgrounds, borders, text colors, icons, and badges.

### Shadows

`ut-shadow-sm`, `ut-shadow-md`, `ut-shadow-lg` for consistent elevation.

### Typography

`a-base-font-family`, `a-base-font-family-serif`, `a-base-font-family-mono` for font stacks.
  

apex-utility-classes/SKILL.md

Display utility classes SKILL.md
---
name: apex-utility-classes
description: Returns Oracle APEX utility CSS classes for styling and layout
---

When asked about APEX utility classes or when styling APEX components, return the relevant CSS classes from the data below.

## Usage

Apply these classes directly to HTML elements. For example:

```html
<div class="padding-md">
  <span class="u-text-bold u-success-text">Success!</span>
</div>

## Available Utility Classes

```
items[179]{name,description,category}:
  col-xxs-[1-12],CSS class prefix for extra extra small screens (479px and below),Grid Layout / Responsive
  col-xs-[1-12],CSS class prefix for extra small screens (480px to 639px),Grid Layout / Responsive
  col-sm-[1-12],CSS class prefix for small screens (640px to 767px),Grid Layout / Responsive
  col-md-[1-12],CSS class prefix for medium screens (768px to 991px),Grid Layout / Responsive
  col-lg-[1-12],CSS class prefix for large screens (992px to 1199px),Grid Layout / Responsive
  col-xl-[1-12],CSS class prefix for extra large screens (1200px to 1399px),Grid Layout / Responsive
  col-xxl-[1-12],CSS class prefix for extra extra large screens (1400px and above),Grid Layout / Responsive
  u-color-1,Applies Color palette #1 as a block color (up to 45),Color and Status Modifiers
  u-color-1-text,Applies Color palette #1 to text (up to 45),Color and Status Modifiers
  u-color-1-bg,Applies Color palette #1 as a background color (up to 45),Color and Status Modifiers
  u-color-1-border,Applies Color palette #1 as a border color (up to 45),Color and Status Modifiers
  u-color-2,Applies Color palette #2 as a block color (up to 45),Color and Status Modifiers
  u-color-2-text,Applies Color palette #2 to text (up to 45),Color and Status Modifiers
  u-color-2-bg,Applies Color palette #2 as a background color (up to 45),Color and Status Modifiers
  u-color-2-border,Applies Color palette #2 as a border color (up to 45),Color and Status Modifiers
  u-color-3,Applies Color palette #3 as a block color (up to 45),Color and Status Modifiers
  u-color-3-text,Applies Color palette #3 to text (up to 45),Color and Status Modifiers
  u-color-3-bg,Applies Color palette #3 as a background color (up to 45),Color and Status Modifiers
  u-color-3-border,Applies Color palette #3 as a border color (up to 45),Color and Status Modifiers
  u-normal,Applies normal state color as a block color,Color and Status Modifiers
  u-normal-text,Applies normal state color to text,Color and Status Modifiers
  u-normal-bg,Applies normal state color as a background color,Color and Status Modifiers
  u-normal-border,Applies normal state color as a border color,Color and Status Modifiers
  u-hot,Applies hot state color as a block color,Color and Status Modifiers
  u-hot-text,Applies hot state color to text,Color and Status Modifiers
  u-hot-bg,Applies hot state color as a background color,Color and Status Modifiers
  u-hot-border,Applies hot state color as a border color,Color and Status Modifiers
  u-warning,Applies warning state color as a block color,Color and Status Modifiers
  u-warning-text,Applies warning state color to text,Color and Status Modifiers
  u-warning-bg,Applies warning state color as a background color,Color and Status Modifiers
  u-warning-border,Applies warning state color as a border color,Color and Status Modifiers
  u-danger,Applies danger state color as a block color,Color and Status Modifiers
  u-danger-text,Applies danger state color to text,Color and Status Modifiers
  u-danger-bg,Applies danger state color as a background color,Color and Status Modifiers
  u-danger-border,Applies danger state color as a border color,Color and Status Modifiers
  u-info,Applies info state color as a block color,Color and Status Modifiers
  u-info-text,Applies info state color to text,Color and Status Modifiers
  u-info-bg,Applies info state color as a background color,Color and Status Modifiers
  u-info-border,Applies info state color as a border color,Color and Status Modifiers
  u-success,Applies success state color as a block color,Color and Status Modifiers
  u-success-text,Applies success state color to text,Color and Status Modifiers
  u-success-bg,Applies success state color as a background color,Color and Status Modifiers
  u-success-border,Applies success state color as a border color,Color and Status Modifiers
  u-opacity-10,Applies 10% opacity to an element,Color and Status Modifiers
  u-opacity-20,Applies 20% opacity to an element,Color and Status Modifiers
  u-opacity-30,Applies 30% opacity to an element,Color and Status Modifiers
  u-opacity-40,Applies 40% opacity to an element,Color and Status Modifiers
  u-opacity-50,Applies 50% opacity to an element,Color and Status Modifiers
  u-opacity-60,Applies 60% opacity to an element,Color and Status Modifiers
  u-opacity-70,Applies 70% opacity to an element,Color and Status Modifiers
  u-opacity-80,Applies 80% opacity to an element,Color and Status Modifiers
  u-opacity-90,Applies 90% opacity to an element,Color and Status Modifiers
  u-opacity-100,Applies 100% opacity to an element,Color and Status Modifiers
  u-shadow-none,Clears any shadow applied to an element,Color and Status Modifiers
  u-shadow-sm,Small shadow applied to an element,Color and Status Modifiers
  u-shadow-md,Medium shadow applied to an element,Color and Status Modifiers
  u-shadow-lg,Large shadow applied to an element,Color and Status Modifiers
  margin-none,No margin,Layout Modifiers
  margin-sm,8 px margin | Specify direction like this: margin-left-sm,Layout Modifiers
  margin-md,16 px margin | Specify direction like this: margin-left-md,Layout Modifiers
  margin-lg,32 px margin | Specify direction like this: margin-left-lg,Layout Modifiers
  margin-auto,Aligns content into the center,Layout Modifiers
  padding-none,No padding,Layout Modifiers
  padding-sm,8 px padding | Specify direction like this: padding-left-sm,Layout Modifiers
  padding-md,16 px padding | Specify direction like this: padding-left-md,Layout Modifiers
  padding-lg,32 px padding | Specify direction like this: padding-left-lg,Layout Modifiers
  w[10-800],Width to specified value in pixels. Sizes in 10px increments,Layout Modifiers
  w[5-100]p,Width to specified percentage. Percentages in 5% increments,Layout Modifiers
  mnw[10-800],Min-width to specified value in pixels. Sizes in 10px increments,Layout Modifiers
  mxw[10-800],Max-width to specified value in pixels. Sizes in 10px increments,Layout Modifiers
  h[10-800],Height to specified value in pixels. Sizes in 10px increments,Layout Modifiers
  mxh[10-800],Max-height to specified value in pixels. Sizes in 10px increments,Layout Modifiers
  u-textStart,Align text to the start of the container,Content Modifiers
  u-textCenter,Align text to the center of the container,Content Modifiers
  u-textEnd,Align text to the end of the container,Content Modifiers
  u-textUpper,Sets the text to use all uppercase,Content Modifiers
  u-textLower,Sets the text to use all lowercase,Content Modifiers
  u-textInitCap,Sets the first letter in each word to use uppercase,Content Modifiers
  u-italics,Italicize text,Content Modifiers
  u-underline,Underline text,Content Modifiers
  u-hidden,Hide text,Content Modifiers
  u-visible,Show text,Content Modifiers
  u-nowrap,Text stays on one line and does not wrap,Content Modifiers
  u-lineclamp-1,Limit text to 1 line, adding ellipsis if it exceeds,Content Modifiers
  u-lineclamp-2,Limit text to 2 lines, adding ellipsis if it exceeds,Content Modifiers
  u-lineclamp-3,Limit text to 3 lines, adding ellipsis if it exceeds,Content Modifiers
  u-lineclamp-4,Limit text to 4 lines, adding ellipsis if it exceeds,Content Modifiers
  u-lineclamp-5,Limit text to 5 lines, adding ellipsis if it exceeds,Content Modifiers
  u-VisuallyHidden,Make text visually hidden, but still accessible for assistive technologies,Content Modifiers
  u-text-heading-2xl,Largest heading size / Alias: u-text-title-1,Content Modifiers
  u-text-heading-xl,Extra large heading / Alias: u-text-title-2,Content Modifiers
  u-text-heading-lg,Large heading / Alias: u-text-title-3,Content Modifiers
  u-text-heading-md,Medium heading / Alias: u-text-title-4,Content Modifiers
  u-text-heading-sm,Small heading / Alias: u-text-title-5,Content Modifiers
  u-text-heading-xs,Extra small heading / Alias: u-text-title-6,Content Modifiers
  u-text-subheading-2xl,Largest subheading / Alias: u-text-subtitle-1,Content Modifiers
  u-text-subheading-xl,Extra large subheading / Alias: u-text-subtitle-2,Content Modifiers
  u-text-subheading-lg,Large subheading / Alias: u-text-subtitle-3,Content Modifiers
  u-text-subheading-md,Medium subheading / Alias: u-text-subtitle-4,Content Modifiers
  u-text-subheading-sm,Small subheading / Alias: u-text-subtitle-5,Content Modifiers
  u-text-subheading-xs,Extra small subheading / Alias: u-text-subtitle-6,Content Modifiers
  u-text-body-xl,Extra large body text,Content Modifiers
  u-text-body-lg,Large body text / Alias: u-text-body-1,Content Modifiers
  u-text-body-md,Medium body text / Alias: u-text-title-2,Content Modifiers
  u-text-body-sm,Small body text / Alias: u-text-title-3,Content Modifiers
  u-text-caption-1,Primary caption text / Alias: u-text-subheading-xs,Content Modifiers
  u-text-caption-2,Secondary caption text / Alias: u-text-subheading-xs,Content Modifiers
  u-text-serif,Serif font family,Content Modifiers
  u-text-sansserif,Sans-serif font family / Alias: u-text-sans-serif,Content Modifiers
  u-text-mono,Monospace font family / Alias: u-fixedFont,Content Modifiers
  u-text-ultralight,Ultra light font weight / Alias: u-text-lighter,Content Modifiers
  u-text-normal,Normal font weight,Content Modifiers
  u-text-semibold,Semi-bold font weight / Alias: u-text-semi-bold,Content Modifiers
  u-text-bold,Bold font weight / Alias: u-bold,Content Modifiers
  u-text-heavy,Heavy font weight / Alias: u-text-bolder,Content Modifiers
  u-hyphenate,Hyphenates long words / Alias: u-hyphen,Content Modifiers
  u-truncate,Truncates text to single line, similar to u-lineclamp-1,Content Modifiers
  u-text-default-color,Default text color,Content Modifiers
  u-text-title-color,Title text color,Content Modifiers
  u-text-subtitle-color,Subtitle text color,Content Modifiers
  u-text-muted-color,Muted text color,Content Modifiers
```

## Categories

### Grid Layout / Responsive

- **Column classes** (`col-{size}-[1-12]`): 12-column grid for different breakpoints
- **Visibility** (`hidden-{size}-up/down`): Show/hide content at breakpoints

**Breakpoints:**
| Size | Range |
|------|-------|
| xxs | 479px and below |
| xs | 480px - 639px |
| sm | 640px - 767px |
| md | 768px - 991px |
| lg | 992px - 1199px |
| xl | 1200px - 1399px |
| xxl | 1400px and above |

### Color and Status Modifiers

- **Palette colors** (`u-color-[1-45]`): Numbered colors with `-text`, `-bg`, `-border` variants
- **Semantic states**: `u-normal`, `u-hot`, `u-warning`, `u-danger`, `u-info`, `u-success`
- **Opacity** (`u-opacity-[10-100]`): Opacity in 10% increments
- **Shadows** (`u-shadow-{none|sm|md|lg}`): Box shadow utilities

### Layout Modifiers

- **Spacing**: `margin-{none|sm|md|lg}`, `padding-{none|sm|md|lg}`
- **Sizing**: `w[10-800]`, `h[10-800]`, `w[5-100]p` (percentage)
- **Float/Align**: `u-pullLeft`, `u-pullRight`, `u-alignTop`, etc.

### Content Modifiers

- **Text alignment**: `u-textStart`, `u-textCenter`, `u-textEnd`
- **Text transform**: `u-textUpper`, `u-textLower`, `u-textInitCap`
- **Typography**: Headings, subheadings, body sizes, font families, weights
- **Truncation**: `u-lineclamp-[1-5]`, `u-truncate`, `u-nowrap`
- **Visibility**: `u-hidden`, `u-visible`, `u-VisuallyHidden`
  

Note I removed some layout utility classes (like u-flex or u-justify-content-center) as LLMs probably are better at just writing CSS directly.

For CSS vars and utility classes, it makes sense to give LLMs the full picture, as understanding the system is crucial. But for icons, it works differently. You mostly just search for icons that match your needs. You don’t want to browse through a list of 1000 icons and their names to find the one you need; you just search for “user icon” and get the relevant results.

This should also work this way for the coding assistant. So I enhanced the Alfred project to also have a CLI to search through its data. And created an alias in my .zshrc to be able to call it from anywhere.

alias apex-grep="node /Users/phartenfeller/Documents/Code/_uc/alfred-apex-documentation/cli.js"

If I search for mail, I get the following results:

apex-grep --type=icons --query=mail
results[15]{name,search,category,synonyms}:
  fa-reply-all,mail,WEB_APPLICATION,""
  fa-reply,mail,WEB_APPLICATION,respond back answer
  fa-envelope-open,mail,WEB_APPLICATION,""
  fa-mail-forward,mail share,WEB_APPLICATION,""
  fa-share,mail forward,WEB_APPLICATION,send forward
  fa-envelope-o,"email,support,email,letter,mail,notification",WEB_APPLICATION,mail email message contact inbox
  fa-envelope,"email,email,letter,support,mail,notification",WEB_APPLICATION,mail email message contact inbox
  fa-home,"main,house",WEB_APPLICATION,dashboard start main landing
  fa-flag-im,"man,isle",FLAG,""
  fa-map-marker-o,"map,pin,location,coordinates,localize,address,travel,where,place",WEB_APPLICATION,""
  fa-flag-ky,"cayman,islands",FLAG,""
  fa-male,"man,user,person,profile",WEB_APPLICATION,""
  fa-map-marker-face-smile,"pin,navigation,location,way finding,directions,emoji,happy",MAPS,""
  fa-map-marker-face-smile-o,"pin,navigation,location,way finding,directions,emoji,happy",MAPS,""
  fa-materialized-view,"",WEB_APPLICATION,""

Then I created another SKILL.md file for icons where I just teach it how to use icons and how to use my search tool to find the right icons for the right use case.

---
name: apex-icons
description: Search and retrieve Oracle APEX icon names and their corresponding CSS classes
---

When asked about APEX icons or when styling APEX components, return the relevant icon names and their corresponding CSS classes from the data below.

## Usage

Apply these classes directly to HTML elements. For example:

```html
<span class="fa fa-times" aria-hidden="true"></span>
```

## Available Icons

Search for icons using the following cli:

```bash
apex-grep --type=icons --query=<search-term>
```

And voilà, the coding assistant can now also utilize icons in an APEX native way.

Conclusion

SKILL.md files are a great way to teach AI coding assistants about niche technologies like Oracle APEX. This will be way more important in the future when APEXlang releases, adding a whole file based language for APEX app definitions. The hope is that we can let assistants work on these definitions directly, so they can create and modify APEX apps in a quick but also accurate way.

I keep experimenting with my SKILL.md files. I also want to solve searching through the APEX PL/SQL documentation, where the assistant can also filter for procedures and then visit the documentation page and extract the relevant information. I will probably share my findings in a future blog post, so stay tuned!

If you are interested in running apex-grep on your machine, the code is open source and available on my GitHub: https://github.com/United-Codes/uc-alfred-orclapex

Also, if you are eager to learn more about agentic AI and get a better understanding of how LLMs work in detail, check out the AI workshop I am hosting.

Other Posts

Comments

Loading comments...