Create File Viewer

SkillWeb & browsing

Create a custom file viewer for the Datagrok file share browser

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Create File Viewer skill

What this skill tells your AI

The instructions your AI receives, as published by datagrok-ai/public in .claude/skills/create-file-viewer/SKILL.md and read by ahel’s review.

Create a custom file viewer that is used by the Datagrok file share browser to display files with specific extensions.

Usage

/create-file-viewer [extensions] [package-path]

Instructions

When this skill is invoked, help the user create a custom file viewer for one or more file extensions. Use the /ui skill for building the UI if necessary.

Step 1: Create the viewer function

Add a function to package.ts (or a separate file imported by it) with the correct annotations. The function must:

  • Accept a single file input
  • Return a view
  • Have the fileViewer tag plus a fileViewer-<ext> tag for each supported extension
//name: myFileViewer
//tags: fileViewer, fileViewer-xyz, fileViewer-abc
//input: file file
//output: view v
export function myFileViewer(file: DG.FileInfo) {
  let view = DG.View.create();

  // Read file content and render it
  file.readAsString().then((content) => {
    let host = ui.div([]);
    // Process and display content
    host.innerText = content;
    view.append(host);
  });

  return view;
}

Step 2: Handle file content

Choose the appropriate method to read file content:

  • file.readAsString() - for text-based files (returns Promise<string>)
  • file.readAsBytes() - for binary files (returns Promise<Uint8Array>)

Example for binary files:

//tags: fileViewer
//input: file file
//output: view v
//meta.fileViewer: mol, sdf, cif
export function structureViewer(file: DG.FileInfo) {
  let view = DG.View.create();
  let host = ui.div([], 'd4-ngl-viewer');

  file
    .readAsBytes()
    .then(bytes => {
      // Process binary content
      let blob = new Blob([bytes]);
      // Render blob...
    });

  view.append(host);
  return view;
}

Key points

  • The function runs when a user clicks on a file with a matching extension in the file share browser
  • The view is displayed in the file preview panel
  • Return the view synchronously; load file content asynchronously inside it
  • meta.fileViewer can take multiple extensions

For extensions that are efficiently DataFrames

  • Return a DG.TableView directly — do not wrap a grid in a custom DG.View
  • Transfer all source metadata to tags (table-level and column-level) so it survives round-trips through the platform
// Good — file viewer for a single-table format
static async previewFoo(file: DG.FileInfo): Promise<DG.View> {
  const bytes = await file.readAsBytes();
  const data = await parseFoo(bytes);
  const df = toDataFrame(data);
  const view = DG.TableView.create(df, false);
  view.name = file.name;
  return view;
}
  • Set df.setTag('source.format', '...') to record where the data came from
  • Preserve column-level metadata (description, format, categories) as tags
  • Use a namespace prefix for format-specific tags (e.g., minitab.version, prism.sheetId)
  • Use the standard description tag for column descriptions

For extensions that contain multiple dataframes

  • Use custom DG.View
  • Show global file metadata on top
  • 'Open all' big button on the ribbon
  • Tab control with pane per dataframe

Behavior

  1. Ask the user which file extension(s) they want to support if not specified
  2. Determine whether the file is text-based or binary to choose readAsString vs readAsBytes
  3. Create the viewer function with correct tags for all specified extensions
  4. Add rendering logic appropriate for the file type

Signals

GitHub stars
72
Forks
32
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
create-file-viewer
Source
github.com/datagrok-ai/public