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

@naniteninja/profile-comparison-lib

v1.0.3

Published

Angular library that renders a side-by-side profile comparison (two profile images, a central draggable shape, and aligned interest lists). It is a **thin client**: you provide a backend URL; the library sends user config to your backend and displays the

Downloads

536

Readme

Profile Comparison Library

Angular library that renders a side-by-side profile comparison (two profile images, a central draggable shape, and aligned interest lists). It is a thin client: you provide a backend URL; the library sends user config to your backend and displays the payload it returns. No API keys or key-entry modals in the library.

You need a backend that implements the profile comparison API (e.g. the profile-comparison-server repo). Provide its base URL via PROFILE_COMPARISON_API_BASE_URL. If not provided, the component shows "Configure backend".


Quick start (copy-paste)

1. Install

npm install @naniteninja/profile-comparison-lib @tensorflow/tfjs @tensorflow-models/universal-sentence-encoder

2. Wire up the module and backend URL

import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import {
  ProfileComparisonLibModule,
  PROFILE_COMPARISON_API_BASE_URL,
} from '@naniteninja/profile-comparison-lib';

@NgModule({
  imports: [HttpClientModule, ProfileComparisonLibModule],
  providers: [
    { provide: PROFILE_COMPARISON_API_BASE_URL, useValue: 'http://localhost:3000/api' },
  ],
})
export class AppModule {}

3. Add the component to a template

<lib-profile-comparison
  [config]="profileConfig"
  [fadeAllEdges]="false"
  (matrixDataChange)="onMatrixData($event)"
  (rawLLMOutputChange)="onRawLLM($event)"
  (viewProfileClick)="onViewProfile($event)"
></lib-profile-comparison>

4. Provide config data in the component

import { IProfileConfig } from '@naniteninja/profile-comparison-lib';

profileConfig: IProfileConfig = {
  person1Interests: [
    'Gaming', 'Programming', 'AI/ML', 'Startups',
    'Blockchain', 'Cybersecurity', 'Web Development', 'Data Science',
  ],
  person2Interests: [
    'AI machine learning', 'Mobile Games', 'Hardware',
    'Data Science', 'Entrepreneurship', 'Design Thinking', 'Blockchain',
  ],
  person3Interests: ['Board Games', 'Machine Learning'],
  user1Image: './assets/user1.jpg',   // data URL or asset path
  user2Image: './assets/user2.jpg',
};

onMatrixData(data: any) { console.log('Matrix:', data); }
onRawLLM(raw: string)   { console.log('LLM:', raw); }
onViewProfile(e: { side: 'left' | 'right' }) {
  console.log('View profile:', e.side);
}

5. Start the backend and run

# Terminal 1 — backend (profile-comparison-server repo)
cd ../profile-comparison-server && npm install && npm start

# Terminal 2 — your app
ng serve

The component renders two profile images with a draggable center shape, semantically aligned interest lists on each side, and a "View Profile" link per side. If the backend is unreachable, a "Configure backend" message appears instead.


Quickstart

  1. Install the package and peer dependencies (including TensorFlow; required for Vite and other bundlers):

    npm install @naniteninja/profile-comparison-lib @angular/core@^20 @angular/common@^20 @tensorflow/tfjs @tensorflow-models/universal-sentence-encoder
  2. Provide the backend URL

    In app.config.ts (or AppModule):

    import { PROFILE_COMPARISON_API_BASE_URL } from '@naniteninja/profile-comparison-lib';
    
    providers: [
      { provide: PROFILE_COMPARISON_API_BASE_URL, useValue: 'https://your-backend.com/api' },
    ]

    Or with a factory (e.g. runtime toggle between backends):

    providers: [{
      provide: PROFILE_COMPARISON_API_BASE_URL,
      useFactory: (backendUrl: BackendUrlService) => () => backendUrl.getBaseUrl(),
      deps: [BackendUrlService],
    }]
  3. Use the component

    Import the module and add the component to a template:

    import { ProfileComparisonLibModule } from '@naniteninja/profile-comparison-lib';
    <lib-profile-comparison [config]="config"></lib-profile-comparison>

What the element looks like

When you use <lib-profile-comparison> in another Angular app you get:

  • Side-by-side profile comparison: two profile images (left and right) with a central draggable “shape” and aligned interest lists between them.
  • Main regions: left image, right image, center shape with text, loading indicator when a request is in progress.
  • Action: “View Profile” on each side; the component emits viewProfileClick with { side: 'left' | 'right' } so the host can route or act.

No key-entry modals or API key inputs appear in the library; all keys and third-party API calls live on your backend.


Full setup (copy-paste)

  1. Create or open an Angular app (Angular ^20.0.0).

  2. Install the library and peer dependencies (TensorFlow is required for dependency optimization in Vite etc.):

    npm install @naniteninja/profile-comparison-lib @angular/core@^20 @angular/common@^20 @tensorflow/tfjs @tensorflow-models/universal-sentence-encoder
  3. Add the backend URL provider in app.config.ts:

    import { ApplicationConfig } from '@angular/core';
    import { provideHttpClient } from '@angular/common/http';
    import { PROFILE_COMPARISON_API_BASE_URL } from '@naniteninja/profile-comparison-lib';
    
    export const appConfig: ApplicationConfig = {
      providers: [
        provideHttpClient(),
        { provide: PROFILE_COMPARISON_API_BASE_URL, useValue: 'https://your-backend.com/api' },
      ],
    };

    Or in AppModule:

    import { PROFILE_COMPARISON_API_BASE_URL } from '@naniteninja/profile-comparison-lib';
    
    @NgModule({
      providers: [
        { provide: PROFILE_COMPARISON_API_BASE_URL, useValue: 'https://your-backend.com/api' },
      ],
    })
    export class AppModule {}
  4. Import the module where you use the component:

    import { ProfileComparisonLibModule } from '@naniteninja/profile-comparison-lib';
    
    @NgModule({
      imports: [ProfileComparisonLibModule, ...],
    })
    export class YourModule {}
  5. Add the component to a template with required [config]:

    <lib-profile-comparison
      [config]="config"
      [fadeAllEdges]="fadeAllEdges"
      (matrixDataChange)="onMatrixData($event)"
      (rawLLMOutputChange)="onRawLLMOutput($event)"
      (viewProfileClick)="onViewProfile($event)"
    ></lib-profile-comparison>
  6. Run the app and ensure your backend is reachable at the URL you provided.


Inputs and outputs

Inputs

  • config (required) — IProfileConfig:

    {
      "person1Interests": ["Gaming", "Programming", "AI/ML"],
      "person2Interests": ["AI machine learning", "Mobile Games", "Data Science"],
      "person3Interests": ["Board Games", "Machine Learning"],
      "user1Image": "data:image/jpeg;base64,...",
      "user2Image": "data:image/jpeg;base64,..."
    }

    user1Image and user2Image can be data URLs or URLs; the library sends them to the backend as needed.

  • fadeAllEdges (optional) — boolean, default false. When true, fades the outer edges of the profile area.

Outputs

  • matrixDataChangeIMatrixData: legend, headers, and rows for the similarity matrix.

    Example payload:

    {
      "legend": [{ "abbr": "Gam", "full": "Gaming" }, { "abbr": "Pro", "full": "Programming" }],
      "headers": ["Gam", "Pro", "AI/ML"],
      "rows": [
        { "label": "Gam", "values": ["1.00", "0.2", "0.5"] },
        { "label": "Pro", "values": ["0.2", "1.00", "0.8"] }
      ]
    }
  • rawLLMOutputChangestring: raw LLM output from the backend (if any).

  • viewProfileClick{ side: 'left' | 'right' }: emitted when the user clicks “View Profile” on the left or right side. Use this to navigate or open a profile page.

    Example:

    onViewProfile(payload: { side: 'left' | 'right' }) {
      this.router.navigate(['/profile', payload.side]);
    }

Backend API contract

The library calls your backend at POST {baseUrl}/profile/compare-full with body { config: IProfileConfig }. The backend should return a display payload (face results, aligned lists, center item, matrix data, raw LLM output). See the profile-comparison-server repo and the lib interface IComparisonPayload for the response shape.


Building the library

ng build profile-comparison-lib

Output is in dist/profile-comparison-lib/ (FESM, typings, package.json). Peer dependencies: Angular ^20.0.0 and TensorFlow (@tensorflow/tfjs, @tensorflow-models/universal-sentence-encoder).