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

@salesflare/social-profile-url-parser

v3.0.3

Published

Node library to parse social profile urls out of text.

Readme

social-profile-url-parser

Node library to parse social profile urls out of text.

npm install @salesflare/social-profile-url-parser
const SocialProfileUrlParser = require('@salesflare/social-profile-url-parser');

const result = SocialProfileUrlParser.parse(`
    slack   angellist   https://angel.co/slack
    SlackHQ twitter     https://twitter.com/SlackHQ
    slack   linkedin    https://www.linkedin.com/company/tiny-speck-inc
`)
result === [
    {
        type: 'angellist',
        type_name: 'AngelList',
        id: 'slack',
        url: 'https://angel.co/slack',
        canonical_url: 'https://angel.co/slack'
    },
    {
        type: 'linkedin',
        type_name: 'LinkedIn',
        id: 'tiny-speck-inc',
        url: 'https://www.linkedin.com/company/tiny-speck-inc',
        kind: 'company',
        canonical_url: 'https://linkedin.com/company/tiny-speck-inc'
    },
    {
        type: 'twitter',
        type_name: 'Twitter',
        id: 'SlackHQ',
        url: 'https://twitter.com/SlackHQ',
        canonical_url: 'https://x.com/SlackHQ'
    }
];

What you get back

parse returns an array with one entry per profile it finds, in the order the types are listed under Supported types rather than the order they appear in the text.

| property | always present | what it holds | | --- | --- | --- | | type | yes | The platform, one of the keys under Supported types | | type_name | yes | The platform's display name, for example LinkedIn | | id | yes | The identifying part of the url | | url | yes | The url as it appeared in the text | | kind | no | What the url points at, see kind | | canonical_url | no | The profile in one agreed upon form, see canonical_url |

id takes whatever form the platform uses: the profile slug for most types, the subdomain for Tumblr and WordPress, an opaque or numeric id for Blogger, VK, Odnoklassniki and LinkedIn's legacy urls, and the business slug for Yelp. It is returned as it was written, so casing is preserved.

id holds only the identifying part, so a query string and a fragment are left off: facebook.com/slackhq?lang=en has an id of slackhq. The one exception is LinkedIn's profile/view?id= urls, where the id is what follows the ? rather than what precedes it.

url keeps the protocol, subdomain, path, query string and fragment that were written, so you can always show or store the url as it was found. The only thing dropped is punctuation that closed the sentence around it, so a url written as (https://x.com/salesflare). does not come back carrying ).. Use canonical_url when you want to compare two urls.

Results are de-duplicated on type, the kind where the platform has one, and id. A profile that appears twice in the same text written two different ways collapses into one entry, holding the last url seen. Since the query string is not part of id, facebook.com/slackhq and facebook.com/slackhq?lang=en count as the same profile.

kind is part of the identity because an id is only unique within the namespace it was written in, so a person and a company can share one. linkedin.com/in/foo and linkedin.com/company/foo stay two entries: they are two different things that happen to have the same slug. What still collapses is the several wordings a platform has for one kind, since those report the same kind: linkedin.com/company/foo, linkedin.com/organization/foo and linkedin.com/companies/foo are one company.

Deprecated: username

id was called username before 3.0.0. Every result still carries a username property holding the same value throughout 3.x, so existing code keeps working, but it will be removed in 4.0.0. Move to id.

kind

kind says what the url points at, for the four platforms that address more than one thing under the same domain. It is always one of the same four values, whatever the platform calls it in its own urls, so you can branch on it without knowing that a LinkedIn person lives under /in/:

| kind | matched urls | | --- | --- | | company | Crunchbase /company/ and /organization/, LinkedIn /company/, /companies/ and /organization/ | | group | Facebook /groups/, Flickr /groups/, LinkedIn /groups/ | | person | Crunchbase /person/, Flickr /people/ and /photos/, LinkedIn /in/, /pub/, /people/, /sales/people/ and /profile/view?id= | | school | LinkedIn /edu/ and /school/ |

kind is left out for every other type, and for a Facebook url that is not a group, since a plain facebook.com/name can be either a person or a page, and a legacy facebook.com/pages/{slug}/{id} page can belong to a company, a person or anything else.

canonical_url

url is the url as it was found in the text. canonical_url is the same profile in one agreed upon form, so that https://twitter.com/SlackHQ, https://www.x.com/SlackHQ and https://mobile.x.com/SlackHQ all come back as https://x.com/SlackHQ. It normalizes the protocol, the www/mobile/country subdomain, the domain where a platform has more than one, and the path where a platform has several interchangeable forms, for example LinkedIn /companies/ and /organization/ to /company/, and Crunchbase /company/ to /organization/.

canonical_url is left out entirely when the matched url cannot be rewritten without guessing, which is the case for two groups of urls. The first is types whose regex matches things that are not interchangeable: a country site that is a separate site, a subdomain that means something different, or a path segment that is optional and therefore ambiguous. The second is LinkedIn /pub/, /people/, /sales/people/ and /profile/view?id= urls, which carry a legacy or opaque member id rather than a public slug. Those still report a kind, so a url can tell you it is a person without being canonicalizable.

A legacy Facebook facebook.com/pages/{slug}/{id} url does get one: the id is the numeric page id, which resolves at the root, so it canonicalizes to https://facebook.com/{id}. The slug is dropped, it is not the page's current vanity name.

The last column of the table below says which types get one. Always check the field is present before using it.

Supported types

Every type accepts http or https and an optional www., and the types with localized sites also accept a country subdomain such as au.linkedin.com or nl-nl.facebook.com.

| type | type_name | matched urls | canonical_url | | --- | --- | --- | --- | | aboutme | About.me | about.me/{id} | yes | | angellist | AngelList | angel.co/{id} | yes | | behance | Behance | behance.com/{id}, behance.net/{id} | yes | | blogger | Blogger | blogger.com/profile/{id} | yes | | coinbase | Coinbase | coinbase.com/{id} | yes | | crunchbase | CrunchBase | crunchbase.com/{person,company,organization}/{id} | yes | | delicious | Delicious | delicious.com/{id} | yes | | digg | Digg | digg.com/users/{id} | yes | | dribbble | Dribbble | dribbble.com/{id} | yes | | facebook | Facebook | facebook.com/{id}, fb.com/{id}, facebook.com/groups/{id}, facebook.com/pages/{slug}/{id} | yes | | flickr | Flickr | flickr.com/{people,photos,groups}/{id} | yes | | foursquare | Foursquare | foursquare.com/{id}, foursquare.com/user/{id} | no | | github | GitHub | github.com/{id} | yes | | gravatar | Gravatar | gravatar.com/{id} | yes | | instagram | Instagram | instagram.com/{id} | yes | | keybase | Keybase | keybase.io/{id} | yes | | lastfm | Last.FM | last.fm/user/{id}, lastfm.com/user/{id} | yes | | linkedin | LinkedIn | linkedin.com/{in,pub,people,company,companies,organization,edu,school,groups}/{id}, linkedin.com/sales/people/{id}, linkedin.com/profile/view?id={id} | yes* | | medium | Medium | medium.com/@{id}, medium.com/{id} | no | | myspace | MySpace | myspace.com/{id} | yes | | ok | Odnoklassniki | ok.ru/{id}, ok.ru/profile/{id} | no | | pandora | Pandora | pandora.com/people/{id} | yes | | pinterest | Pinterest | pinterest.{tld}/{id} | no | | plancast | Plancast | plancast.com/{id} | yes | | quora | Quora | quora.com/{id}, quora.com/profile/{id} | no | | reddit | Reddit | reddit.com/user/{id} | yes | | slideshare | Slideshare | slideshare.net/{id} | yes | | tumblr | Tumblr | {id}.tumblr.com | yes | | twitter | Twitter | twitter.com/{id}, x.com/{id} | yes | | vimeo | Vimeo | vimeo.com/{id} | yes | | vk | VK | vk.com/{id} | yes | | wordpress | Wordpress | {id}.wordpress.com | yes | | xing | Xing | xing.com/{id}, xing.com/profile/{id} | no | | yahoo | Yahoo | {profile,me,local}.yahoo.com/{id} | no | | yelp | Yelp | yelp.{tld}/biz/{id} | no | | youtube | YouTube | youtube.com/{id}, youtube.com/{user,channel,c}/{id} | no |

* every LinkedIn url except /pub/, /people/, /sales/people/ and /profile/view?id=.

type is the value to store and branch on, since it stays put. type_name is only a display name and may be retitled if a platform rebrands.

x.com is matched as type: 'twitter' so that existing stored profiles keep working. Only canonical_url uses the x.com domain.