npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@lipme/vue-blast-viewer

v1.0.16

Published

Interactive BLAST alignment visualizer for Vue 3

Readme

@lipme/vue-blast-viewer

An interactive, responsive, and visually rich Vue 3 component for displaying biological BLAST (Basic Local Alignment Search Tool) results. It combines visual alignment graphics, summary hit tables, and detailed pairwise alignment views into a single, unified biotech-styled dashboard.


🌟 Features

  • Interactive SVG Alignment Map: Visualizes matching segments (HSPs) aligned against the query sequence, color-coded by standard alignment score metrics. Hovering reveals detailed tooltips; clicking jumps straight to the alignment details.
  • Searchable & Sortable Table: Displays descriptions, Max Score, Total Score, Query Coverage (overlapping intervals merged), E-values, and Identity percentages. Supports exporting the current filtered results directly to a TSV file.
  • Pairwise Alignment Visualizer: Formats alignment text in blocks of 60 characters with colored annotations highlighting exact matches, gaps, and mismatches, with exact forward and reverse coordinate tracking.
  • Custom Accession Linkers: Dynamically redirects accession IDs to custom endpoints using string templates ({accession}).
  • Modern Responsive Design: A glassmorphic dark-theme tailored for scientific applications, supporting drag-and-drop file uploading and raw JSON pasting.

🚀 Getting Started

1. Installation

Install the package via npm (or yarn/pnpm/bun):

npm install @lipme/vue-blast-viewer

To run the sandbox demonstration locally:

# Sourcing Node (if using NVM)
source $HOME/.nvm/nvm.sh && nvm use node

# Install dependencies
npm install

# Start the local Vite development server
npm run dev

# Compile and check for production build validation
npm run build

💻 Component Usage

Basic Usage

To render a standard BLAST result, supply the parsed BLAST JSON output (supporting -outfmt 15 formats) directly to the component.

<script setup lang="ts">
import { ref } from 'vue';
import { BlastViewer } from '@lipme/vue-blast-viewer';
import myBlastData from './data/blast_result.json';

const blastResult = ref(myBlastData);
</script>

<template>
  <div class="container">
    <BlastViewer :blast-data="blastResult" />
  </div>
</template>

Custom Accession Linking: String Template

You can set templates for query and subject accessions independently:

<template>
  <BlastViewer 
    :blast-data="blastResult" 
    query-link="https://www.ncbi.nlm.nih.gov/nuccore/{accession}"
    subject-link="https://www.ncbi.nlm.nih.gov/protein/{accession}" 
  />
</template>

Dynamic Accession Linking

You can use computed properties to resolve links dynamically based on your application state. For example, conditionally linking the Query sequence to NCBI, but redirecting Subject protein accessions to UniProtKB for a specific dataset:

<script setup lang="ts">
import { ref, computed } from 'vue';
import { BlastViewer } from '@lipme/vue-blast-viewer';
import myBlastData from './data/blast_result.json';

const blastResult = ref(myBlastData);
const isProt = true; // Example

// Link query directly to NCBI
const queryLinkTemplate = computed(() => {
  const db = isProt ? 'protein' : 'nuccore';
  return `https://www.ncbi.nlm.nih.gov/${db}/{accession}`;
});

// Redirect Subject accessions conditionally
const subjectLinkTemplate = computed(() => {
  if (isProt) {
    return 'https://www.uniprot.org/uniprotkb/{accession}/entry';
  }
  return 'https://www.ncbi.nlm.nih.gov/nucleotide/{accession}';
});
</script>

<template>
  <BlastViewer 
    :blast-data="blastResult" 
    :query-link="queryLinkTemplate"
    :subject-link="subjectLinkTemplate" 
  />
</template>

⚙️ Properties (Props)

| Prop | Type | Required | Default | Description | | :--- | :--- | :---: | :--- | :--- | | blastData | BlastRoot \| null | Yes | null | The parsed JSON output payload matching standard NCBI BLAST JSON structures. | | queryLink | string | No | null | String template to resolve the link for the Query ID in the metadata header (use {accession}). | | subjectLink | string | No | null | String template to resolve the links for Subject/target accessions in the hit list and alignments. |


📊 Data Structures Supported

The component expects a standard BLAST JSON archive root structure matching the NCBI format:

export interface BlastRoot {
  BlastOutput2: Array<{
    report: {
      program: string;
      version: string;
      reference: string;
      search_target: { db: string };
      results: {
        search: {
          query_id: string;
          query_title: string;
          query_len: number;
          hits: Array<{
            num: number;
            description: Array<{
              id: string;
              accession: string;
              title: string;
              taxid?: number;
            }>;
            len: number;
            hsps: Array<{
              num: number;
              bit_score: number;
              score: number;
              evalue: number;
              identity: number;
              query_from: number;
              query_to: number;
              hit_from: number;
              hit_to: number;
              query_strand?: string;
              hit_strand?: string;
              align_len: number;
              gaps: number;
              qseq: string;
              hseq: string;
              midline: string;
            }>;
          }>;
        };
      };
    };
  }>;
}

🎨 Theme Customization

The aesthetics are configured via CSS variables. You can easily adjust the visual signature of the components by overriding these variables in your root stylesheet:

:root {
  /* Core Spacings */
  --font-sans: 'Plus Jakarta Sans', sans-serif;
  --font-mono: 'Fira Code', monospace;
  
  /* Theme Base Color Modifiers */
  --bg-primary: #0a0e17;
  --bg-card: rgba(20, 27, 45, 0.65);
  
  /* BLAST Score Color Coding overrides */
  --blast-score-low: #4b5563;       /* < 40 score */
  --blast-score-mid-low: #3b82f6;   /* 40 - 50 score */
  --blast-score-mid: #10b981;       /* 50 - 80 score */
  --blast-score-mid-high: #ec4899;  /* 80 - 200 score */
  --blast-score-high: #ef4444;      /* >= 200 score */
}