HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
defunkt
jquery-pjax
JavaScript2011–2026
defunkt / jquery-pjax

jquery-pjax

pushState + ajax = pjax

34Distinct people
38Mentions
1Explicit recommenders
16.6KGitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

pushState + ajax = pjax

GitHub

Where it is used

No documented product use was verified in the last source check.

What people are saying

Anyone interested in something like this should also check out PJAX. Push State and AJAX. https://github.com/defunkt/jquery-pjax This is what GitHub uses between tabs on its…

seanconaty used a recommendation phrase. One indexed comment matches. This is a phrase match, not a verdict.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

Mentioned in the same Hacker News threads. That is not proof they are substitutes.

This week on Hacker News

Nov 7–Nov 14 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/14/2026, 3:56:07 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year38 dated mentions

Observed mentions: 2011-03-31 21:43:03 UTC to 2026-03-07 20:40:20 UTC.

02462011-01-01 00:00:00 UTC to 2012-01-01 00:00:00 UTC (exclusive): 2 mentions; 2 submissions, 0 comments20112012-01-01 00:00:00 UTC to 2013-01-01 00:00:00 UTC (exclusive): 7 mentions; 0 submissions, 7 comments2013-01-01 00:00:00 UTC to 2014-01-01 00:00:00 UTC (exclusive): 4 mentions; 0 submissions, 4 comments2014-01-01 00:00:00 UTC to 2015-01-01 00:00:00 UTC (exclusive): 5 mentions; 1 submissions, 4 comments2015-01-01 00:00:00 UTC to 2016-01-01 00:00:00 UTC (exclusive): 2 mentions; 1 submissions, 1 comments2016-01-01 00:00:00 UTC to 2017-01-01 00:00:00 UTC (exclusive): 3 mentions; 0 submissions, 3 comments2017-01-01 00:00:00 UTC to 2018-01-01 00:00:00 UTC (exclusive): 3 mentions; 0 submissions, 3 comments2018-01-01 00:00:00 UTC to 2019-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments20182019-01-01 00:00:00 UTC to 2020-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 4 mentions; 0 submissions, 4 comments2021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments2023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2024-01-01 00:00:00 UTC to 2025-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2025-01-01 00:00:00 UTC to 2026-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2026-01-01 00:00:00 UTC to 2027-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments. Incomplete calendar period.2026*

* An incomplete calendar period is marked with an outlined bar. Its count is not directly comparable with a full period.

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20112011-01-01 00:00:00 UTC2012-01-01 00:00:00 UTC220
20122012-01-01 00:00:00 UTC2013-01-01 00:00:00 UTC707
20132013-01-01 00:00:00 UTC2014-01-01 00:00:00 UTC404
20142014-01-01 00:00:00 UTC2015-01-01 00:00:00 UTC514
20152015-01-01 00:00:00 UTC2016-01-01 00:00:00 UTC211
20162016-01-01 00:00:00 UTC2017-01-01 00:00:00 UTC303
20172017-01-01 00:00:00 UTC2018-01-01 00:00:00 UTC303
20182018-01-01 00:00:00 UTC2019-01-01 00:00:00 UTC202
20192019-01-01 00:00:00 UTC2020-01-01 00:00:00 UTC000
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC404
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC000
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC202
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC101
20242024-01-01 00:00:00 UTC2025-01-01 00:00:00 UTC101
20252025-01-01 00:00:00 UTC2026-01-01 00:00:00 UTC101
2026 (partial)2026-01-01 00:00:00 UTC2027-01-01 00:00:00 UTC101

From the project README

An excerpt from the repository, fetched Nov 13, 2026.

Read the project’s introduction
pjax = pushState + ajax pjax is a jQuery plugin that uses ajax and pushState to deliver a fast browsing experience with real permalinks, page titles, and a working back button. pjax works by fetching HTML from your server via ajax and replacing the content of a container element on your page with the loaded HTML. It then updates the current URL in the browser using pushState. This results in faster page navigation for two reasons: No page resources (JS, CSS) get re-executed or re-applied; If the server is configured for pjax, it can render only partial page contents and thus avoid the potentially costly full layout render. Status of this project jquery-pjax is largely unmaintained at this point. It might continue to receive important bug fixes, but its feature set is frozen and it's unlikely that it will get new features or enhancements. Installation pjax depends on jQuery 1.8 or higher. npm $ npm install jquery-pjax standalone script Download and include jquery.pjax.js in your web page: curl -LO https://raw.github.com/defunkt/jquery-pjax/master/jquery.pjax.js Usage $.fn.pjax The simplest and most common use of pjax looks like this: $(document).pjax('a', '#pjax-container') This will enable pjax on all links on the page and designate the container as #pjax-container. If you are migrating an existing site, you probably don't want to enable pjax everywhere just yet. Instead of using a global selector like a, try annotating pjaxable links with data-pjax, then use 'a[data-pjax]' as your selector. Or, try this selector that matches any <a data-pjax href=> links inside a <div data-pjax> container: $(document).pjax('[data-pjax] a, a[data-pjax]', '#pjax-container') Server-side configuration Ideally, your server should detect pjax requests by looking at the special X-PJAX HTTP header, and render only the HTML meant to replace the contents of the container element (#pjax-container in our example) without the rest of the page layout. Here is an example of how this might be done in Ruby on Rails: def index if request.headers['X-PJAX'] render :layout => false end end If you'd like a more automatic solution than pjax for Rails check out Turbolinks. Check if there is a pjax plugin for your favorite server framework. Also check out RailsCasts #294: Playing with PJAX. Arguments The synopsis for the $.fn.pjax function is: $(document).pjax(selector, [container], options) selector is a string to be used for click event delegation. container is a string selector that uniquely identifies the pjax container. options is an object with keys described below. pjax options key default description timeout 650 ajax timeout in milliseconds after which a full refresh is forced push true use pushState to add a browser history entry upon navigation replace false replace URL without adding browser history entry maxCacheLength 20 maximum cache size for previous container contents version a string or function returning the current pjax version scrollTo 0 vertical position to scroll to after navigation. To avoid changing scroll position, pass false. type "GET" see $.ajax dataType "html" see $.ajax container CSS selector for the element where content should be replaced url link.href a string or function that returns the URL for the ajax request target link eventually the relatedTarget value for pjax events fragment CSS selector for the fragment to extract from ajax response You can change the defaults globally by writing to the $.pjax.defaults object: $.pjax.defaults.timeout = 1200 $.pjax.click This is a lower level function used by $.fn.pjax itself. It allows you to get a little more control over the pjax event handling. This example uses the current click context to set an ancestor element as the container: if ($.support.pjax) { $(document).on('click', 'a[data-pjax]', function(event) { var container = $(this).closest('[data-pjax-container]') var containerSelector = '#' + container.id $.pjax.click(event, {container: containerSelector}) }) } NOTE Use the explicit $.support.pjax guard. We aren't using $.fn.pjax so we should avoid binding this event handler unless the browser is actually going to use pjax. $.pjax.submit Submits a form via pjax. $(document).on('submit', 'form[data-pjax]', function(event) { $.pjax.submit(event, '#pjax-container') }) $.pjax.reload Initiates a request for the current URL to the server using pjax mechanism and replaces the container with the response. Does not add a browser history entry. $.pjax.reload('#pjax-container', options) $.pjax Manual pjax invocation. Used mainly when you want to start a pjax request in a handler that didn't originate from a click. If you can get access to a click event, consider $.pjax.click(event) instead. function applyFilters() { var url = urlForFilters() $.pjax({url: url, container: '#pjax-container'}) } Events All pjax events except pjax:click & pjax:clicked are fired from the pjax container element. event cancel arguments notes event lifecycle upon following a pjaxed link pjax:click ✔︎ options fires from a link that got activated; cancel to prevent pjax pjax:beforeSend ✔︎ xhr, options can set XHR headers pjax:start xhr, options pjax:send xhr, options pjax:clicked options fires after pjax has started from a link that got clicked pjax:beforeReplace contents, options before replacing HTML with content loaded from the server pjax:success data, status, xhr, options after replacing HTML content loaded from the server pjax:timeout ✔︎ xhr, options fires after options.timeout; will hard refresh unless canceled pjax:error ✔︎ xhr, textStatus, error, options on ajax error; will hard refresh unless canceled pjax:complete xhr, textStatus, options always fires after ajax, regardless of result pjax:end xhr, options event lifecycle on browser Back/Forward navigation pjax:pops
Read the full README on GitHub

What Hacker News says

38 sources
I particularly like commit c8010802f [0]. Here's a small portion of it: - ## Credits - - Octotree uses the following open-source software: - - - [jQuery](https://github.com/jquery/jquery) - - [jQuery UI](https://github.com/jquery/jquery-ui) - - [jstree](https://github.com/vakata/jstree) - - [file-icons-js](https://github.com/websemantics/file-icons-js) - - [keymaster](https://github.com/madrobby/keymaster) - - [jquery-pjax](https://github.com/defunkt/jquery-pjax) - - [github-dark](https://github.com/StylishThemes/GitHub-Dark) -- [0]: https://github.com/ovity/octotree/commit/c8010802f5f04bd3f52... -- EDIT: Fixed URL.
In Octotree – Proprietary Firefox extension contains AGPL-licensed code
> On Github, comments continually change. They become “outdated” and disappear when attached to a line that has been changed You can view them if you go to the commit on which the comment was made. >Furthermore, patches from multiple authors can’t mix in a Github pull request. The person opening the pull request “owns” it. Actually, no. Pull requests are for reveiwing one branch. If that branch is accessible to multiple authors they can be collaborate on that branch > annotating the hunk headers with which C functions are affected Seems like you can do this with git as well : https://stackoverflow.com/a/16528858/3528640 > and the choice of various algorithms such as “patience.” Again, possible with git > Finally, there’s nothing to stop the mailing list style of collaboration from adapting to emerging diff formats, such as structural diff
Read the rest
s I don't think Git/Github developers will sit idle when improved collaboration methods are discovered > The bulk of communication around a new feature is in its proposal, not around the subsequent code This can be done by opening issues or by simply using a Google doc. Mailing lists are not a very good solution to this. There is a lot of extraneous garbage that needs to be parsed before getting to the meaty stuff etc etc. Most of author's complaints seems to not be entirely accurate > Challenges for mailing lists One big challenge is also how good Github is, the UX is well done. Almost every time I wanted to do something there is button right there to do it. Also, it is very fast. Projects like PJAX[1] has meant that Github is miles ahead of competition. I have used Github, Gerrit etc and I have to say, once you started using Github, there is no going back [1] https://github.com/defunkt/jquery-pjax When a Github user clicks on a link, it is converted to an XHR request and then only the part of the page that needs to change are fetched. The page is updated and browser history is manipulated using PushState to not break the back button !
In Mailing lists vs Github
I think both of them are awesome and have great communities. Especially seeing as webpack has stabilized. If you're a startup, it's tempting for many founders to go in headfirst with a Vue or React. In my opinion, it's rarely necessary, and in the end a lot of the stuff has to be thrown out if underlying foundations change. I see it as web development's version of premature optimization. On the other hand, when I kept all my work in django templates, erb, blade, etc. and just script JS by hand, there's less of a penalty when the data flow changes. When I was using a JS framework, the refactoring was so painful I seriously considered throwing the whole thing out and starting from scratch. Heh, I'd have been better off not buying in so early on. As a stop-gap, I'm using pjax. (https://github.com/defunkt/jquery-pjax) My plan is after stuff i
Read the rest
s solid and in production and the product/service/business is moving forward, taking an incremental approach to moving to vue/react/etc. P.S. kudos to react for removing the patent stuff in v16.
In Vue.js vs. React: what happened in 2017
You can build complex user flows with JavaScript on top of server rendered views. Ajax works great with server side rendering, see Pjax https://github.com/defunkt/jquery-pjax or Intercooler http://intercoolerjs.org/ The server is rendering JSON anyway, more or less just as expensive to serve HTML. Besides, the bottleneck is usually database access. It's a false separation and forces you to expose far more than necessary. It's nice to have my full database available on every page render without needing to define explicit endpoints. I also like having forms generated from database models.
In Vue.js and Brunch: Webpack Alternative

Showing the 15 most recent of 38 sources. Enable JavaScript to search and browse every indexed mention.

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.