Skip to content

Conversation

@trim21
Copy link

@trim21 trim21 commented Dec 25, 2025

add quickjs runtime support based on https://github.com/quickjs-ng/quickjs

use option -Djavascript=quickjs

  • test new backend could run simple js script without error
  • check javascript runtime compatible
  • re-enable full ci jobs
  • fix the meson wrap install quickjs-ng can't be found by meson.build

@trim21 trim21 force-pushed the feat/quickjs branch 5 times, most recently from 5779044 to 9c42955 Compare December 25, 2025 18:46
@trim21 trim21 marked this pull request as ready for review December 25, 2025 18:49
@trim21 trim21 marked this pull request as draft December 25, 2025 19:13
@avih
Copy link
Member

avih commented Dec 25, 2025

Thanks. This looks interesting.

You should have read contribute.md and followed it, however, at the very least, this PR is missing:

  • A good commit message (explaining why this PR is needed, considerations or decisions which were taken, compatibility notes about existing scripts, other changes in behavior or requirements, and anything else worth mentioning).
  • The code doesn't follow the coding style - at the very least indentation should be 4 spaces, but the new files are indented with 2-spaces.
  • There are no docs changes at all, but there probably should be at least some.

So please read the contribution guidelines fully and carefully, and follow them as best as you can.

Preferably, please also split it into 2 commits: one which only renames the current js (c) files to ...-mujs (with the respective meson.build changes), so that it still builds the same with mujs but with the new file names, and then another commit which adds the qjs files (and build changes).

Also, the PR currently disables almost all of the CI builds - don't do that. Please restore them, and in general don't make changes outside the scope of the PR.

Build/deps questions:

  • Why does it use quickjs-ng rather than upstream quickjs?
  • Can it work with upstream quickjs too? if yes, how, and what would be the differences in behavior?
  • Do I read correctly that by default it uses quickjs (ng) instead of mujs? (judging by the fact that in meson.build it checks for quickjs before mujs, and tries to enable it if it's "auto" or "enabled").
  • Why does the linux CI build (in build.yml) clone the quickjs-ng repo? shouldn't meson know how to find it on its own, only by name?

Some questions regarding the actual code and behavior:

  • Did you write it yourself?
  • Do you have prior experience with embedding quickjs and its C interface? if yes, can you share such projects?
  • Other than (hopefully) performance, and supporting newer JS features, should existing scripts work unmodified when quickjs is used?
  • Did you test with at least some existing scripts at user-scripts that they still work as expected? if yes, which?
  • What kinds of differences in behavior should be expected? (behavior on errors, or anything else which comes to mind).
  • As far as I can tell the (almost) only comment in these new hundreds of lines of code is "based on the mujs code". Please add comments where you see fit, and some introduction comments explaining the approach in this file, how quickjs is integrated at the C and JS levels, how should new code be added, things to be careful of, etc, so that if someone else wants to make changes, it's easy to get started. Also, comments for actual functions would also be welcome, especially where non-obvious things take place.

Integration:

As far as I can tell, the build replaces mujs with quickjs by default, and if we keep it as either mujs or quickjs, then at least for now mujs should remain the default. We'd need a lot of feedback and experience before we can replace the engine, because backward compatibility is very important.

However, I did have another idea, and I'd appreciate some feedback on it by others: what if we allow both to be built together, and use the mujs backend with .js files, and the quickjs backend with .qjs files?

This way people could experiment with quckjs with the standard build (assuming both are enabled), without interfering with any existing scripts?

I think that technically it should be pretty easy to do.

Thoughts?

@trim21
Copy link
Author

trim21 commented Dec 26, 2025

Thansk for your quick reply!

I'll read contributing.md again.

Also, the PR currently disables almost all of the CI builds - don't do that. Please restore them, and in general don't make changes outside the scope of the PR.

I do these because this PR is yet in developing, I disable build ci jobs and set quickjs on default to do a quick testing on ci (in my GitHub fork), I'll enable them before it's finally ready.

Do I read correctly that by default it uses quickjs (ng) instead of mujs? (judging by the fact that in meson.build it checks for quickjs before mujs, and tries to enable it if it's "auto" or "enabled").
Why does the linux CI build (in build.yml) clone the quickjs-ng repo? shouldn't meson know how to find it on its own, only by name?

The building/ci config part is the minimal change to make it work.
There is indeed quickjs-ng in wrapdb, I didn't try it yet, I'll refine it later.

Why does it use quickjs-ng rather than upstream quickjs?
Can it work with upstream quickjs too? if yes, how, and what would be the differences in behavior?

the upstream quickjs is a makefile only project, it doesn't have meson or cmake build file, make it very hard to use as a library in our project.

So I don't know if it works with upstream quickjs, someone may need to add a cmake file or meson.build file first.

Did you write it yourself?
Do you have prior experience with embedding quickjs and its C interface? if yes, can you share such projects?

With LLM, this code complies with our license. And no.

Other than (hopefully) performance, and supporting newer JS features, should existing scripts work unmodified when quickjs is used?
Did you test with at least some existing scripts at user-scripts that they still work as expected? if yes, which?

I would expect it, but I haven't run any tests yet, this is still WIP.

What kinds of differences in behavior should be expected? (behavior on errors, or anything else which comes to mind).
As far as I can tell the (almost) only comment in these new hundreds of lines of code is "based on the mujs code". Please add comments where you see fit, and some introduction comments explaining the approach in this file, how quickjs is integrated at the C and JS levels, how should new code be added, things to be careful of, etc, so that if someone else wants to make changes, it's easy to get started. Also, comments for actual functions would also be welcome, especially where non-obvious things take place.

OK I'll add them later.

@avih
Copy link
Member

avih commented Dec 26, 2025

Also, the PR currently disables almost all of the CI builds - don't do that. Please restore them, and in general don't make changes outside the scope of the PR.

I do these because this PR is yet in developing, I disable build ci jobs and set quickjs on default to do a quick testing on ci (in my GitHub fork), I'll enable them before it's finally ready.

Thanks. We can keep it like that for now.

However, I'd want you to enable also the x86-64 msvc build, and one of the mingw build, so that windows users would be able to download and play locally with the resulting CI builds.

the upstream quickjs is a makefile only project, it doesn't have meson or cmake build file, make it very hard to use as a library in our project.

So I don't know if it works with upstream quickjs, someone may need to add a cmake file or meson.build file first.

OK, we can keep quickjs-ng for now, but if this ever gets merged, we'd need to consider this more carefully, because generally upstream projects should be preferred, unless there are good reasons to not use them, and I don't know yet that "being a makefile only project" is a good enough reason.

I haven't run any tests yet, this is still WIP.

But you did explicitly mark it as "ready for review", right?

A PR which was marked as ready for review should be considered at least reasonably ready, even if not fully ready. And this means that at the very least the author tested that it generally works. And this is a lot of code - 1500 lines. A lot can go wrong with 1500 lines of C code which no one tested...

If it was not tested at all, then this should have been stated clearly. The contribution guidelines state clearly that the author should test it before submitting it. We can't guess what the author did or think, and your PR has literally zero info which you wrote about it. We simply can't guess it. This is information which you need to provide.

Before we continue, a reminder that there are few subjects which you didn't respond to, specifically, for instance splitting it into two commits, and supporting both backends together - according to the filename extension, so I'd appreciate if you could fill the missing replies to my original questions. Thanks.

Did you write it yourself?
Do you have prior experience with embedding quickjs and its C interface? if yes, can you share such projects?

With LLM, this code complies with our license. And no.

Thanks. Since we don't yet have a policy for contributions using LLMs, we'd have to figure it out as we go, so I'd appreciate your patience in answering the following questions.

Feel free to also volunteer interesting relevant info also beyond the questions.

How much experience do you have with C? did you write or contribute meaningful C code which you wrote on your own? if yes, mind giving some examples?

What was the process of opening this PR? how did you start? how did you iterate? what kinds of problems came up during the development? how were these problems solved? Feel free to also provide additional info on the process which might interest others.

How much of the code was written by an LLM, and how much of it is your own? how much code did you touch/fixed yourself?

To what degree do you understand this code? (for instance "not at all", or "only the overall structure", or "absolutely every bit of it", or anything else in between).

Did you go over every line of this code and confirmed to yourself it looks good? Or in other words, did you review all this code carefully yourself?

If I asked you questions about the code - approaches, structures, construct, integrations with mpv code, and anything else really, do you think you'd be able to answer them reasonably good without the help of an LLM?

I know you said "I haven't run any tests yet", but does it mean you really didn't even run it? never tried even a single one-line js script? If you did run it and did some tests, please do elaborate what you tested and how.

Thanks.

@trim21
Copy link
Author

trim21 commented Dec 26, 2025

But you did explicitly mark it as "ready for review", right?

A PR which was marked as ready for review should be considered at least reasonably ready, even if not fully ready. And this means that at the very least the author tested that it generally works. And this is a lot of code - 1500 lines. A lot can go wrong with 1500 lines of C code which no one tested...

Yeah, that's a mistake, so I change it back to draft. This is my first PR, so I'm also a little bit confusing with the [RFC] prefix in PR title recommanded from contributing.md, does it has same meaning with draft in github?

@avih
Copy link
Member

avih commented Dec 26, 2025

Yeah, that's a mistake, so I change it back to draft.

Thanks.

This is my first PR, so I'm also a little bit confusing with the [RFC] prefix in PR title recommanded from contributing.md, does it has same meaning with draft in github?

No worries, and really thanks for the PR. I do find it very interesting.

Also, don't worry about the exact procedure with "[RFC]" and draft status etc. The most important thing is that you explain clearly where it stands, what's the status, what was tested, what's still to do, etc, and of course any questions which you might have and which we might be able to help with.

@trim21
Copy link
Author

trim21 commented Dec 26, 2025

Thanks. Since we don't yet have a policy for contributions using LLMs, we'd have to figure it out as we go, so I'd appreciate your patience in answering the following questions.

Feel free to also volunteer interesting relevant info also beyond the questions.

How much experience do you have with C? did you write or contribute meaningful C code which you wrote on your own? if yes, mind giving some examples?

Ididn't write much pure-c, I did use pure-c in some my toy project.

But I do write c++ ( and some c when it's necessary, for example, exporting a so ) for a living, and many works on binding language A to lanaguge B.

What was the process of opening this PR? how did you start? how did you iterate? what kinds of problems came up during the development? how were these problems solved? Feel free to also provide additional info on the process which might interest others.

I already have write some js script in mpv so I know what the js runtime need to provide, for example, the mp object.

Then I read the docs and example of quickjs-ng

Then find out the exported API (the mp_scripting_js in this case) that mpv need in javascript_mujs.c and write a declaration, then let LLM fill the implementation. then I check its generated code to fix compilation error and api wrong API usage then manully fix them.

How much of the code was written by an LLM, and how much of it is your own? how much code did you touch/fixed yourself?

I'd call 80% llM and 20% me.

To what degree do you understand this code? (for instance "not at all", or "only the overall structure", or "absolutely every bit of it", or anything else in between).

I think it's between "only the overall structure" and "absolutely every bit of it". I understand the overall calling structure.

Did you go over every line of this code and confirmed to yourself it looks good? Or in other words, did you review all this code carefully yourself?

yes.

If I asked you questions about the code - approaches, structures, construct, integrations with mpv code, and anything else really, do you think you'd be able to answer them reasonably good without the help of an LLM?

yeah, I didn't write much c but have no difficulty understanding them.

I know you said "I haven't run any tests yet", but does it mean you really didn't even run it? never tried even a single one-line js script? If you did run it and did some tests, please do elaborate what you tested and how.

I only run the tests that what we have in meson.build. didn't run the mpv executable with js script. that's the next move I was planning, after we put the "rename" in a seprated PR commit.

@avih
Copy link
Member

avih commented Dec 26, 2025

Also, since this is your first PR, let me answer one question which you didn't ask:

If you want to make changes, don't open a new PR. Just keep changing this PR (splitting it to several commits, or adding commits, etc).

Thanks.

@avih
Copy link
Member

avih commented Dec 26, 2025

Thanks. Good answers. I think we can continue ;)

I only run the tests that what we have in meson.build. didn't run the mpv executable with js script. that's the next move I was planning

OK. Once you test it a bit, please post some info about what you tested and what were the results (before you make further changes to the code).

after we put the "rename" in a seprated PR.

As noted - don't open a new PR. just split this one into two commits. Thanks.

@avih
Copy link
Member

avih commented Dec 26, 2025

Preferably, please also split it into 2 commits: one which only renames the current js (c) files to ...-mujs (with the respective meson.build changes) ...

Eh, do use underscore (javascript_mujs.c etc). I.e. the current file names are fine, just split it into the two commits as requested.

@trim21
Copy link
Author

trim21 commented Dec 26, 2025

Thanks. Good answers. I think we can continue ;)

So I guess you are worried that I submit some LLM generated code but doesn't have the ability to address the code review?

@avih
Copy link
Member

avih commented Dec 26, 2025

So I guess you are worried that I submit some LLM generated code but doesn't have the ability to address the code review?

Yes. But you seems to have done at least some work on your own, so hopefully we're good.

I would have preferred that you'd know every last bit of all the code as if you wrote it yourself, instead of reading and understanding it to answer questions which come up, but for now, let's continue and see how it goes.

Also, to help us (and you) keep track of things, I'd appreciate if you could maintain a todo list at the first message. It doesn't have to be fancy, just a list of items and their status in plain text, which you'll keep up to date ("not done yet", "done but not tested", "finished and should be ready", or any other descriptions which would describe the items status).

It's also fine to add items over time, and it doesn't have to be in any particular order, but it should be clear what's the status of each item, and what remains to do.

Some things which come to mind, and which might fit in such list (feel free to add items now or over time, and generally write and maintain it yourself):

  • Coding style.
  • Good commit message.
  • Split into two commits: mujs rename, and adding quickjs.
  • Support both mujs and quickjs in the same build, and choose which one to use according to the filename extension.
  • Introduction comment explaining how quickjs work, how js/c functions work, how it's integrated with mpv, what needs careful attention when writing code, how should new code be added, etc.
  • Testing with existing scripts, what's known to work, what's known to be broken.
  • Decide about quickjs upstream vs quickjs-ng.
  • Even without the final build.yml, add also msvc x86-64 and one mingw build.
  • Remove the temporary changes to build.yml before the final review.
  • Things to do with meson.build.

etc.

Also, one question I had which hopefully you'd be able to answer:

mujs doesn't have require and doesn't have setTimeout and setInterval, and those are implemented at defaults.js.

But quickjs does have all three (and also require is newer standard, while at defaults.js we have the older CommonJS support), and additionally, the timer-related APIs require integration with some event loop, and in the case of mpv, with mpv's event loop.

How do these work with quickjs in general?

How do these work with quickjs in mpv?

(if you're not sure about the answers right now, feel free to add it to your todo list).

@trim21 trim21 force-pushed the feat/quickjs branch 2 times, most recently from 5278d2a to 24cd172 Compare December 26, 2025 15:18
@trim21
Copy link
Author

trim21 commented Dec 26, 2025

Also, one question I had which hopefully you'd be able to answer:

mujs doesn't have require and doesn't have setTimeout and setInterval, and those are implemented at defaults.js.

But quickjs does have all three (and also require is newer standard, while at defaults.js we have the older CommonJS support), and additionally, the timer-related APIs require integration with some event loop, and in the case of mpv, with mpv's event loop.

How do these work with quickjs in general?

How do these work with quickjs in mpv?

(if you're not sure about the answers right now, feel free to add it to your todo list).

I need to do some testing. if these API from quickjs has same behavoir we can remove them from shim to provide same API to users, or fix the behavoir in another shim.

@avih
Copy link
Member

avih commented Dec 26, 2025

I need to do some testing.

Right. For what it's worth, these are the kinds of questions about the code which I was referring to, which I hoped you'd already know the answers pretty much on the spot, because regardless of who wrote it - you are submitting it as your code, and as the author, these are things which you should have known and figured out already (and addressed where applicable) while writing the code. So FYI.

You need to really know the code well before we can discuss it. So if you need to take some time to go over every bit again to understand it fully - take your time, but please do understand it well - as if you wrote it yourself and came up with all the solutions yourself.

if these API from quickjs has same behavoir we can remove them from shim to provide same API to users

I'm not sure about that, and there should first be some way to tell if they really do behave the same. For instance, the require code was tested for conformance (with CommonJS) using the official (as it gets) test suite, with some additions specific to mpv, and the timers APIs are also conformat to some version of HTML, and both of them should have relevant comments and links at defaults.js.

Also the fact that it looks like something behaves correctly, for instance with the timers API, doesn't mean that it's also necessarily correct. Timer related things typically depend on some kind of event loop or threading or system timers APIs, and the way it's integrated with the mpv model is important to get right. With mpv it's tied to mpv's event loop, and it's important to keep it integrated well with this event loop.

So once you get to it, I suggest you follow the questions I asked in that order (and explain it to me too). I.e. first how does quickjs handle "require" and timer APIs on its own, then understand how the current mujs (and lua) code works with timers in mpv, and then how it works with quickjs in the context of mpv, and which changes are required, if any.

For what it's worth, at least for starters, the simplest approach would likely be to ensure that the existing implementations at defaults.js are still used also with quickjs, but that's a guess. You'd need to figure out what's possible here, and then we can discuss the options to decide which approach would be most appropriate.

@ahaoboy
Copy link

ahaoboy commented Jan 1, 2026

Thank goodness someone finally started working on it.

I'm very curious about how much performance qjs can improve.

For performance testing, you can use v8v7 in mpv: https://github.com/ahaoboy/mpv-v8v7

Alternatively, download portable_config in your browser mpv-build.

Here is my experience using both qjs and qjs-ng:

qjs-ng has better community support and is updated more frequently.

Unfortunately, the two projects (qjs and qjs-ng) cannot be merged in the short term:
quickjs-ng/quickjs#374

In terms of performance, qjs is currently slightly faster than qjs-ng.
This performance gap is already being investigated and worked on in qjs-ng:
quickjs-ng/quickjs#1172

@avih
Copy link
Member

avih commented Jan 2, 2026

@trim21 are you still working on it? Any issues or interesting observations so far?

If you solved some problems or have some questions, I'd appreciate if you could share them here and we can discuss them, because for big PR's like this, it's better to know it's in the right direction before it's "ready", because otherwise there might be big changes to make, so preferably we could find good solutions together as you progress. Thanks.

@trim21
Copy link
Author

trim21 commented Jan 2, 2026

I'm still working on this but it's holiday so no new progress

@avih
Copy link
Member

avih commented Jan 3, 2026

When you answered this:

Did you go over every line of this code and confirmed to yourself it looks good? Or in other words, did you review all this code carefully yourself?

yes.

The PR code contained this:

  const char *norm_err_proto_js =
      "if (Error().stackTrace && !Error().stack) {\n"
      "    Object.defineProperty(Error.prototype, 'stack', {\n"
      "        get: function() { return this.name + ': ' + this.message + "
      "this.stackTrace; }\n"
      "    });\n"
      "}\n";

  r = eval_string(ctx, norm_err_proto_js, "@/norm_err.js");

(which is currently commented out at the PR - at the javascript_quickjs.c changes, but at the time you replied "yes" it was not commented).

This is a mujs-specific workaround, as the comment explains, and copied effectively verbatim from our mujs code, just without the comment:

mpv/player/javascript.c

Lines 409 to 421 in a3350e2

// The spec defines .name and .message for Error objects. Most engines also set
// a very convenient .stack = name + message + trace, but MuJS instead sets
// .stackTrace = trace only. Normalize by adding such .stack if required.
// Run this before anything such that we can get traces on any following errors.
static const char *norm_err_proto_js = "\
if (Error().stackTrace && !Error().stack) {\
Object.defineProperty(Error.prototype, 'stack', {\
get: function() {\
return this.name + ': ' + this.message + this.stackTrace;\
}\
});\
}\
";

If you reviewed every line, how come this was at the code to begin with, when it's not required with quickjs?

I need an honest reply here, because if we can't trust your replies, then it's not worth spending any more time on you.

Here's my guess: you didn't actually review every line meaningfully, because otherwise this is something which should have raised some flag for you - either you couldn't understand what it does and should have dug deeper, checking where it comes from and why, or your "meaningful review" was largely just scrolling over the code in the hope to identify some obvious stuff - which we definitely can't call "go over every line of this code and confirmed to yourself it looks good? Or in other words, did you review all this code carefully yourself".

Now please provide your honest reply.

If it's indeed something along the lines of my guess, then I'm willing to let this one go, but it cannot happen again, or else I'll just close this PR.

You need to KNOW the code as if you wrote it yourself. You need to KNOW that each function is used, and used correctly. You need to KNOW the reason for each condition at the code, and confirm that indeed all code paths are reachable, or otherwise being there for a good reason - which you should KNOW. You need to know why EVERY line exists and is needed.

I hope you understand the point. Regardless of how the initial code was generated, you submit it as your own code, but if that's not the case, then we can't waste time on it.

@trim21
Copy link
Author

trim21 commented Jan 3, 2026

Here's my guess: you didn't actually review every line meaningfully, because otherwise this is something which should have raised some flag for you

This is actually a differnt issue, the "javascript runtime compatible".

In my understand, the stack trace property on Error is not part of any ES standard, so different engine has different behavoir. there is even no stackTrace on MDN.

and the js code referenced here is warpped in a if block, so it won't do any harm, whether we keep it or remove it. The real problem is that how quickjs behave and that't not something can be find based on simply code reading.

And now is commented, not becauase I find that quickjs has or has not these property, but I find some bug and I'm debugging them, and I know they are caused by wrong usage of c-api and not caused by these js code. If you trace the diff between force pushes, you will find that I remove some JS_FreeValue, which cause some double-free on some js value, it's expected by quickjs that the JS_SetPropertyStr take the ownership and I should not free them.

@avih
Copy link
Member

avih commented Jan 3, 2026

And now is commented, not becauase I find that quickjs has or has not these property,

Not great, mainly because whoever submits such PR should have known, or have learned, that this property already exists with quickjs.

And if the author knew that but still left this code, then a comment should have explained why it's there. Indeed, something like this, but more specific:

This is actually a differnt issue, the "javascript runtime compatible".

In my understand, the stack trace property on Error is not part of any ES standard, so different engine has different behavoir. there is even no stackTrace on MDN.

but without me having to ask about it. It's unused code - but maybe kept there for a good reason. Only the author knows the reason to write code which is knowingly unused, so a comment must have explained why it's there and what it might solve.

I find some bug and I'm debugging them, and I know they are caused by wrong usage of c-api and not caused by these js code.

Good. That's what we expect from code authors. Keep doing that.

Keep in mind that in the future, we expect this (and more) to be done before the PR is submitted, but for now, let's continue.

As I mentioned earlier, I would greatly appreciate if you share the issues you find, even small ones - like the double free which you mentioned, and your fixes and reasoning where applicable, and also please share concerns or decisions you make along the way.

It's also possible that you identify issues for which you don't yet have fixes or solutions. This is normal and not an issue - as long as we know about it. In some cases we might be able to help, in others it might require some investigation by you.

In both cases (fixed issues, or identified issues or questions which are not yet addressed), you should add them to your todo list at the first comment, so that it's easier to track the progress and steps which were taken, and have an up-to-date status of known issues, and fixed issues.

The reason is that it's quite a big PR, which currently has some issues - which we don't know of and which are not necessarily easy to identify. How it makes progress is important, so that we can assess if it makes progress in the right direction, and that it's worth spending our time on it. So please report as much as possible, and ask as much as you need as you make progress. Thanks.

@trim21
Copy link
Author

trim21 commented Jan 21, 2026

@avih

new commits for 4 things:

1: move js engine to player/javascript/quickjs.c and player/javascript/mujs.c which is suggessted from reviewer.
2: refactor the code that convert js value to mpv_node, quickjs provide value tag so it's not a switch-case instead of a multiple if(JS_IsT(...)) call
3: refactor the jsre/quickjs, it now compile a Array<String> to Array<RegExpt> on init and compile to a matching function, that take Array<RegExpt> and string, so the for-loop control flow code can be written in js instead of complex c code.
4: some minor change like reduce the alloc.

Also I test some of my simple scripts, like mp.add_key_binding("esc", ...);, so far it works fine, I don'r have many complex js scripts now, I'll also test some later.

Next steps I'll re-check my implements of each native funcitons.

@avih
Copy link
Member

avih commented Jan 21, 2026

new commits for 4 things: ...

I'm not seeing this commit in this PR or in your branch - https://github.com/trim21/mpv/commits/feat/quickjs/ .

Please show me where it is.

Also, from now on please only add commits, without modifying existing commits, and without rebasing on new commits in mpv-master. This PR is relatively isolated in the grand scheme of things, and this would make it easier to follow the changes in this PR over time.

When the time comes, we can squash and rebase as needed, but until further notice, please no rebases and no modifications of existing commits.

@trim21
Copy link
Author

trim21 commented Jan 21, 2026

new commits for 4 things: ...

I'm not seing this commit in this PR or in your branch - https://github.com/trim21/mpv/commits/feat/quickjs/ .

Please show me where it is.

here fa1ee02

Also, from now on please only add commits, without modifying existing commits, and without rebasing on new commits in mpv-master. This PR is relatively isolated in the grand scheme of things, and this would make it easier to follow the changes in this PR over time.

When the time comes, we can squash and rebase as needed, but until further notice, please no rebases and no modifications of existing commits.

ok, I'll use merge to resolve the new conflict.

@avih
Copy link
Member

avih commented Jan 21, 2026

ok, I'll use merge to resolve the new conflict.

What new conflicts? however it is now, from now on just add new commits with fixes and changes. Don't use merge, don't rebase, just add commits and push to this branch.

@trim21
Copy link
Author

trim21 commented Jan 21, 2026

What new conflicts? however it is now, from now on just add new commits with fixes and changes. Don't use merge, don't rebase, just add commits and push to this branch.

There are conflicts between head branch and base branch, which is already resolved by rebasing so it's gone now.

@avih
Copy link
Member

avih commented Jan 21, 2026

Also, why do you keep renaming the files? I already agreed on javascript_mujs.c and javascript_quickjs.c. This only makes it harder to follow changes.

@avih
Copy link
Member

avih commented Jan 21, 2026

There are conflicts between head branch and base branch

I don't understand what you mean. You can update "base" master branch (pull), just don't rebase the feat/quickjs branch. Instead, only add commits to this branch and push this branch so that the new commits become part of this PR.

It's not a problem that it's not based on top of current mpv master, and we can rebase it later, when I request it.

If you don't know how to do that and it's causing you problems, then just don't pull anything anymore. Not your master branch and not any other branch. Just add commits to the quickjs branch and push them.

Do you have any issue with that, or other conflicts or problems?

@trim21
Copy link
Author

trim21 commented Jan 21, 2026

I don't understand what you mean. You can update "base" master branch (pull), just don't rebase the feat/quickjs branch. Instead, only add commits to this branch and push this branch so that the new commits become part of this PR.

It's not a problem that it's not based on top of current mpv master, and we can rebase it later, when I request it.

If you don't know how to do that and it's causing you problems, then just don't pull anything anymore. Not your master branch and not any other branch. Just add commits to the quickjs branch and push them.

Do you have any issue with that, or other conflicts or problems?

OK, sorry, let me explain it.

I mean I won't merge mpv:master into trim21:feat/quickjs just because it's old. If there are some conflicts in the future, for example someone touch javascript.c or javascript part of meson.build, I'll resolve them with merge, not rebase.

Is this what you are expecting? Or I should leave the conflicts as-is untill you ask to resolve it?

@trim21
Copy link
Author

trim21 commented Jan 21, 2026

@ahaoboy It's basically runnable, I test some basic scripts, but it still need some bug finding and javascript runtime compatible checking, would you like to provide some help with testing it with some real world scripts?

@avih
Copy link
Member

avih commented Jan 21, 2026

Also, from now on in any new commits, please do only one thing in each commit, and describe it nicely.

Example of not good commit construction:

Commit 4db558f says "revert some whitespace only change and use meson wrap to install quicjs-ng", however:

  • These are two unrelated things, so they should be in two commits.
  • It does more than than - it actually also removes some debug changes in defaults.js. So this should have been a 3rd commit.

Commit fa1ee02 says "fix js type checks and jsre" sounds simple, and already wrong, because two different things should mean two commits. however, it actually does a lot more than these two things:

  • It renames javascript_mujs.c to mujs.c and similarly with quickjs. This should have been a stand alone commit, but even better, there was no need for that at all because we already agreed to use the earlier names.
  • It changes the indentation in mujs.c from 4 spaces to two. This should have not happened at all.
  • It changes all the include statements (again, should be its own commit - if needed at all, which I doubt).
  • It add tons of comments, which is great, but again, should have been its own commit.

And I can go on and on and on.

As I said, don't edit existing commits. Only add new ones.

Every commit should do one thing.

Don't mix no-op changes (style, braces, indentation, etc) with actual code changes, except if it's directly related to actual code changes which the commit does. Otherwise - do no-op changes in their own commits.

Due to these "weird" changes, especially in commit fa1ee02, I feel that maybe something is wrong in your development process.

Could you please describe how you work on this?

Which operating system? which editor?

Are you generally comfortable with git from the command line? how do you use git and add commits?

OK, sorry, let me explain it.

I mean I won't merge mpv:master into trim21:feat/quickjs just because it's old. If there are some conflicts in the future, for example someone touch javascript.c or javascript part of meson.build, I'll resolve them with merge, not rebase.

Is this what you are expecting? Or I should leave the conflicts as-is untill you ask to resolve it?

Please first answer the questions above about your development process.

And then I still don't understand what conflicts you're talking about.

Assuming you have a local git-clone of mpv (on your local system), you have at least two branches there: "master", and "quickjs" (or maybe "feat/quickjs", I don't know the name of your local branch).

So if you only push commits to the quickjs branch, there would be no conflict. Conflicts can only happen if you try to rebase the quickjs branch (typically on top of master), or try to merge the master into the quickjs branch.

But if you only add commits to the quickjs branch, and then push the quickjs branch to github, then there should be no conflicts at all.

@ahaoboy
Copy link

ahaoboy commented Jan 21, 2026

@ahaoboy It's basically runnable, I test some basic scripts, but it still need some bug finding and javascript runtime compatible checking, would you like to provide some help with testing it with some real world scripts?

https://github.com/mpv-easy/mpv-easy/releases/download/nightly/mpv-easy-windows.zip
You can download it via the link and then extract it to the portable_config directory. This is a UI script based on React. mpv-easy is probably the most complex js script currently available. If it can run, then at least in terms of functionality, it should be able to meet the needs of most scripts.

This script includes some polyfills that may already exist in qjs. If it fails to run or encounters other issues, I can provide an ES6 version with the polyfills removed.

UPDATE:
I found the ES6 script that previously worked with rqjs and Deno.
You need to manually overwrite portable_config\scripts\mpv-easy.js with mpv-easy-es6.js.

https://github.com/mpv-easy/mpv-easy/releases/download/v0.1.14/mpv-easy-es6.js
https://github.com/mpv-easy/mpv-easy/releases/download/v0.1.14/mpy-easy-windows.zip

@trim21
Copy link
Author

trim21 commented Jan 22, 2026

Due to these "weird" changes, especially in commit fa1ee02, I feel that maybe something is wrong in your development process.

Could you please describe how you work on this?

Which operating system? which editor?

Are you generally comfortable with git from the command line? how do you use git and add commits?

This is unrelated to what OS and editor I'm using or how I use git. I'll do only one thing in each commit.

Please first answer the questions above about your development process.

And then I still don't understand what conflicts you're talking about.

Assuming you have a local git-clone of mpv (on your local system), you have at least two branches there: "master", and "quickjs" (or maybe "feat/quickjs", I don't know the name of your local branch).

So if you only push commits to the quickjs branch, there would be no conflict. Conflicts can only happen if you try to rebase the quickjs branch (typically on top of master), or try to merge the master into the quickjs branch.

But if you only add commits to the quickjs branch, and then push the quickjs branch to github, then there should be no conflicts at all.

We're going around in circles. Off course I know git won't prevent anyone commiting more commits on top of a branch, but for a PR, merging conflict will prevent ci generating a merging commit to test PR in ci, right? For example, you can still review mpv-player/mpv/pull/8130 but github can't try to compile the code.

So hypothetically, if I'm the author or this PR, should I merge [mpv-player:master](https://github.com/mpv-player/mpv/tree/master into trim21:feat/quickjs or should I wait?

image

@trim21
Copy link
Author

trim21 commented Jan 22, 2026

@ahaoboy It's basically runnable, I test some basic scripts, but it still need some bug finding and javascript runtime compatible checking, would you like to provide some help with testing it with some real world scripts?

https://github.com/mpv-easy/mpv-easy/releases/download/nightly/mpv-easy-windows.zip You can download it via the link and then extract it to the portable_config directory. This is a UI script based on React. mpv-easy is probably the most complex js script currently available. If it can run, then at least in terms of functionality, it should be able to meet the needs of most scripts.

This script includes some polyfills that may already exist in qjs. If it fails to run or encounters other issues, I can provide an ES6 version with the polyfills removed.

UPDATE: I found the ES6 script that previously worked with rqjs and Deno. You need to manually overwrite portable_config\scripts\mpv-easy.js with mpv-easy-es6.js.

https://github.com/mpv-easy/mpv-easy/releases/download/v0.1.14/mpv-easy-es6.js https://github.com/mpv-easy/mpv-easy/releases/download/v0.1.14/mpy-easy-windows.zip

I'll have a try. Would you mind you explain how react works in mpv? Do we have DOM in somewhere I didn't find, or it's just the philosophy of react?

@avih
Copy link
Member

avih commented Jan 22, 2026

Please don't add any more commits for now, and don't make any changes in the existing commits. I'll add more info later.

@ahaoboy
Copy link

ahaoboy commented Jan 22, 2026

I'll have a try. Would you mind you explain how react works in mpv? Do we have DOM in somewhere I didn't find, or it's just the philosophy of react?

react-reconciler allows react to run on any device with display capabilities. In MPV, I use OsdOverlay to simulate the DOM, and then add some Flex layout algorithms to simulate simple UI components. However, this is very performance-intensive, which is why I'm interested in this PR.

@avih
Copy link
Member

avih commented Jan 22, 2026

This is unrelated to what OS and editor I'm using or how I use git.

I'd like to be the judge of that.

As I said few times, this is a very big PR, and most of it was generated by LLM, at least initially. I need to first establish that I can trust you to work with the code on your own, to understand it, to make useful progress and fixes on your own, etc. My hunch is that you can do that, but I don't know that yet.

So I want to understand your process, your tools (editor, git, whatever), your use of the tools, and how you make progress. Mostly to evaluate it, but also from curiosity. Once I can establish that you can deal with the process on your own, I'll stop asking these questions.

To understand how you make progress, I already requested several times that you post about any new issue you identify, and how you address it. One issue at a time.

And then, not only you make dozens of changes/fixes without posting about any of them on its own, you also do that in one commit, and in addition to whatever issues you addressed, you also do refactoring, renames, adding a directory, change indentation of a complete file which should have not been touched at all, change almost all include statements, and more - all of those in this single commit - fa1ee02 .

This does not give me any confidence that you have a good process which you control well.

While it's true that the later commits do look better, and the initial editing of the first 3 commits as I requested does suggest that you can use git well, a commit like fa1ee02 raises a huge red flag for me, and I need to understand how/why it happened.

So yes, I do want you to answer these questions, one by one, even if you think they're unrelated to this commit:

Could you please describe how you work on this?

Which operating system? which editor?

Are you generally comfortable with git from the command line? how do you use git and add commits?

For example, here's my tools:

  1. I'm using windows and linux, and usually use vscodium editor, but sometimes also notepad++ or geany.
  2. I'm reasonably comfortable with git, and do all the git changes via command line (clone/pull/commit/ammed/rebase/branch/push/etc), usually without needing to use the git help. I also sometimes use gitk to review the code history and track code changes over time, but I don't use it to make any git changes.

And this is my process when I'm working on fixing some issue in any project:

  1. Identify some unexpected symprom (crash, other unexpected behavior, etc). Usually it's either by a bug report by a user, or a symptom which I encountered myself.
  2. Identify whether it's indeed unexpected, usually by checking the docs. Sometimes it's actually documented to behave like this, so this is not actually a bug. Buf if it is a bug, then continue.
  3. Test whether I can reproduce the issue myself, locally. If I can't, then request from whoever reported this issue more details, until I can reproduce it.
  4. Isolate the issue. To ensure the symptom is unrelated to some config or script which I have locally, I disable all custom configs/scripts. In mpv it means runnng mpv --no-config ...., and if it involves scripting, then also creating a minimal script (usually 1-5 lines) which can reproduce the issue.
  5. Look at the code and try to find the reason to this behavior. Sometimes it's easy to identify the reason, and sometimes it's not obvious. If it's not obvious, then some debugging is needed (debugger, adding printf in relevant code junctions, etc). Until I can identify and understand the reason at the code.
  6. Decide how to fix it. Sometimes it's enough to just work with the code, but sometimes I need to look at external references (documentations of various libraries/APIs, examples of similar code elsewhere at the current project or other projects, etc).
  7. Write the code/fix, compile, run the new binary and confirm that the issue is indeed fixed. Sometimes this requires several iterations.
  8. Once it seems to fix the issue, create a new commit: git add ..., git commit, edit the title and message in vim, with a summary in the title, and a commit message which gives more details about the symptom, the reason at the code for the bug, and how the new code addresses it. If some decisions were taken, then explain them too.
  9. Refine. I then review the commit, either using git show, or in gitk. I ensure the code changes look good, follow the project/file style as appropriate, ensure it doesn't touch any unrelated code, read the commit message again, etc. If something needs refinements, I make the changes and amend the commit, until I'm happy with it.
  10. Push the commit to github, and don't make any further changes to that commit anymore, unless the reviewer requested some changes, and which case I amend the commit again, and force-push it.

Now it's your turn. Your OS and tools/editors, how comfortable are you with git, and what's your general process in this PR, starting with how you identify an issue, and ending with pushing it to github.

@avih
Copy link
Member

avih commented Jan 22, 2026

Now it's your turn. Your OS and tools/editors, how comfortable are you with git, and what's your general process in this PR, starting with how you identify an issue, and ending with pushing it to github.

In addition to those, please tell me also whether you used LLM with any of the new commits, and if yes, which commits.

Note that so far all these are general questions. I'm not asking about any specific code change.

But after you answer what I asked, and I insist - only after you answered them, if you know how come commit fa1ee02 ended up with so many changes, some of them completely unrelated to what this commit says it does, then please explain this too.

Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants