> > \usepackage{l3io,xr2} instead and commented out the \RequirePackage. > actually it works if there is a blank line after the \RequirePackage This is just a problem because of the current mix of l3 and 2e code. The rules are that after l3names.cls is read, there are no special conventions about what comes after \RequirePackage, but before that the first non-space token after the } had better be a token whether read with l3 or 2e conventions. so after \usepackage{l3io,xr2} you need a blank line, or \par or [1998/06/01]. The problem is that \usepackage & \RequirePackage look ahead to see if there is an optional argument coming up. l3names.sty redefines the lookahead to make sure that @_: are all letters at that point but before that redefinition has happened, _ is not a letter so if you go \usepackage{l3io,xr2} % no blank line here \tex_def:D ..... then \usepackage looks ahead and tokenises \tex. The packages run correctly but when they finish, you get an undefined command \tex followed by an attempt to typeset _def:D. Probably the clearest way to avoid this is always to Require l3names first, and on its own \RequirePackage{l3names} \RequirePackage{l3io,xr2} as the second \RequirePackage is safe to be read under any convention. There are alternative ways of handling the switching but all the ones I tried so far have similar bad effects somewhere. Suggestions accepted... David